+static void NONRETURNING docheck(void) {
+#ifndef DEBUG
+ /* This subprocess exits with status 0 if the parent should die,
+ * 1 if it should not, and something else if it fails horribly.
+ */
+ int sfd, r, remain;
+ unsigned char *p;
+ struct opening_msg opening_mbuf;
+ struct request_msg request_mbuf;
+ unsigned long endmagic;
+ struct sigaction sig;
+ struct sockaddr_un ssockname;
+
+ openlog(USERVDCHECK_LOGIDENT,LOG_NDELAY|LOG_PID,USERVD_LOGFACILITY);
+
+ sigemptyset(&sig.sa_mask);
+ sig.sa_flags= 0;
+ sig.sa_handler= SIG_IGN;
+ if (sigaction(SIGPIPE,&sig,0)) { syslog(LOG_ERR,"ignore sigpipe"); exit(1); }
+
+ sig.sa_handler= SIG_DFL;
+ if (sigaction(SIGALRM,&sig,0)) { syslog(LOG_ERR,"default sigalarm"); exit(1); }
+
+ sfd= socket(AF_UNIX,SOCK_STREAM,0);
+ if (!sfd) { syslog(LOG_ERR,"ignore sigpipe"); exit(1); }
+
+ assert(sizeof(ssockname.sun_path) > sizeof(RENDEZVOUS));
+ ssockname.sun_family= AF_UNIX;
+ strcpy(ssockname.sun_path,RENDEZVOUS);
+
+ r= connect(sfd,(struct sockaddr*)&ssockname,sizeof(ssockname));
+ if (r) {
+ if (errno == ECONNREFUSED || errno == ENOENT)
+ { syslog(LOG_WARNING,"real uservd daemon is not running: %m"); exit(0); }
+ syslog(LOG_ERR,"unable to connect to uservd daemon: %m"); exit(1);
+ }
+
+ r= alarm(USERVD_MYSELF_TIMEOUT);
+ if (r<0) { syslog(LOG_ERR,"set alarm for read: %m"); exit(1); }
+ remain= sizeof(opening_mbuf); p= (unsigned char*)&opening_mbuf;
+ while (remain) {
+ r= read(sfd,p,remain);
+ if (r<0) { syslog(LOG_ERR,"read from server: %m"); exit(1); }
+ if (r==0) { syslog(LOG_ERR,"unexpected EOF from server"); exit(1); }
+ remain-= r; p+= r;
+ }
+ if (opening_mbuf.magic != OPENING_MAGIC) {
+ syslog(LOG_WARNING,"magic number mismatch");
+ exit(0);
+ }
+ if (memcmp(opening_mbuf.protocolchecksumversion,protocolchecksumversion,PCSUMSIZE)) {
+ syslog(LOG_WARNING,"protocol checksum mismatch");
+ exit(0);
+ }
+ if (opening_mbuf.overlordpid != overlordpid) {
+ syslog(LOG_WARNING,"overlord pid mismatch");
+ exit(0);
+ }
+ memset(&request_mbuf,0,sizeof(request_mbuf));
+ request_mbuf.magic= REQUEST_MAGIC;
+ request_mbuf.clientpid= -1;
+ request_mbuf.serviceuserlen= 0;
+ request_mbuf.servicelen= 0;
+ request_mbuf.loginnamelen= 0;
+ request_mbuf.spoofed= 0;
+ request_mbuf.cwdlen= 0;
+ request_mbuf.overridelen= -1;
+ request_mbuf.callinguid= -1;
+ request_mbuf.ngids= 0;
+ request_mbuf.nreadfds= 0;
+ request_mbuf.nwritefds= 0;
+ request_mbuf.nargs= 0;
+ request_mbuf.nvars= 0;
+ r= write(sfd,&request_mbuf,sizeof(request_mbuf));
+ if (r==sizeof(request_mbuf)) {
+ endmagic= REQUEST_END_MAGIC;
+ write(sfd,&endmagic,sizeof(endmagic));
+ }
+ syslog(LOG_NOTICE,"uservd[%ld] is running",(long)overlordpid);
+#endif
+ exit(1);
+}
+
+static void NONRETURNING startupsyscallerr(const char *what) {
+ fprintf(stderr,
+ "uservd: system call failed during startup:\n"
+ "uservd: %s: %s\n",
+ what,strerror(errno));
+ exit(4);
+}
+