1 # include "sendmail.h" 2 3 #ifndef DAEMON 4 SCCSID(@(#)daemon.c 3.7 02/26/82 (w/o daemon mode)); 5 #else 6 7 # include <sys/socket.h> 8 # include <wellknown.h> 9 # include <net/in.h> 10 11 SCCSID(@(#)daemon.c 3.7 02/26/82 (with daemon mode)); 12 13 /* 14 ** DAEMON.C -- routines to use when running as a daemon. 15 */ 16 /* 17 ** GETREQUESTS -- open mail IPC port and get requests. 18 ** 19 ** Parameters: 20 ** none. 21 ** 22 ** Returns: 23 ** none. 24 ** 25 ** Side Effects: 26 ** Waits until some interesting activity occurs. When 27 ** it does, a child is created to process it, and the 28 ** parent waits for completion. Return from this 29 ** routine is always in the child. 30 */ 31 32 getrequests() 33 { 34 for (;;) 35 { 36 register int pid; 37 auto int st; 38 register int port; 39 40 /* 41 ** Wait for a connection. 42 */ 43 44 while ((port = getconnection()) < 0) 45 { 46 syserr("getrequests: getconnection failed"); 47 sleep(30); 48 } 49 50 /* 51 ** Create a subprocess to process the mail. 52 */ 53 54 # ifdef DEBUG 55 if (Debug > 1) 56 printf("getrequests: forking (port = %d)\n", port); 57 # endif DEBUG 58 59 pid = fork(); 60 if (pid < 0) 61 { 62 syserr("daemon: cannot fork"); 63 sleep(10); 64 close(port); 65 continue; 66 } 67 68 if (pid == 0) 69 { 70 /* 71 ** CHILD -- return to caller. 72 ** Verify calling user id if possible here. 73 */ 74 75 InChannel = fdopen(port, "r"); 76 OutChannel = fdopen(port, "w"); 77 initsys(); 78 # ifdef DEBUG 79 if (Debug > 1) 80 printf("getreq: returning\n"); 81 # endif DEBUG 82 return; 83 } 84 85 /* 86 ** PARENT -- wait for child to terminate. 87 ** Perhaps we should allow concurrent processing? 88 */ 89 90 # ifdef DEBUG 91 if (Debug > 1) 92 { 93 sleep(2); 94 printf("getreq: parent waiting\n"); 95 } 96 # endif DEBUG 97 98 (void) wait(&st); 99 close(port); 100 } 101 } 102 /* 103 ** GETCONNECTION -- make a connection with the outside world 104 ** 105 ** Parameters: 106 ** none. 107 ** 108 ** Returns: 109 ** The port for mail traffic. 110 ** 111 ** Side Effects: 112 ** Waits for a connection. 113 */ 114 115 struct sockaddr_in SendmailAddress = { AF_INET, IPPORT_SMTP }; 116 117 getconnection() 118 { 119 register int s; 120 char *host = "localhost"; 121 struct sockaddr otherend; 122 123 /* 124 ** Set up the address for the mailer. 125 */ 126 127 SendmailAddress.sin_addr.s_addr = rhost(&host); 128 129 /* 130 ** Try to actually open the connection. 131 */ 132 133 # ifdef DEBUG 134 if (Debug) 135 printf("getconnection (%s)\n", host); 136 # endif DEBUG 137 138 s = socket(SOCK_STREAM, 0, &SendmailAddress, SO_ACCEPTCONN); 139 140 # ifdef DEBUG 141 if (Debug) 142 printf("getconnection: %d\n", s); 143 # endif DEBUG 144 accept(s, &otherend); 145 146 return (s); 147 } 148 149 #endif DAEMON 150