# 2.11BSD#431 - /usr/src/new/nntp/server/spawn.c

##### Functions

    spawn             X
    xfer_timeout      X

       1: #ifndef lint
       2: static  char    *sccsid = "@(#)spawn.c	1.6	(Berkeley) 2/6/88";
       3: #endif
       4:
       5: #include "../common/conf.h"
       6:
       7: #include "common.h"
       8:
       9: #include <signal.h>
      10:
      11: #ifdef XFER_TIMEOUT
      12: static int  xfer_lines;
      13: static int  old_xfer_lines;
      14: #endif
      15:
      16: static char tempfile[256];
      17:
      18: /*
      19:  * spawn -- create a child process with the input from the client
      20:  * as stdin.
      21:  *
      22:  *	Parameters:	"path" is the path of the program to invoke.
      23:  *			"name" is the name to call the program.
      24:  *			"flag" is a single flag to be passed to the program.
      25:  *			"cont_code" is the response code to transmit
      26:  *			on successful startup.
      27:  *			"err_code" is the response code to transmit when
      28:  *			something goes wrong.
      29:  *
      30:  *	Returns:	-1 on non-zero return from child,
      31:  *			0 on error before fork/exec,
      32:  *			1 otherwise.
      33:  *
      34:  *	Side effects:	Creates and removes temporary file;
      35:  *			accepts input from client; forks and execs.
      36:  *			Can time out if XFER_TIMEOUT is defined.
      37:  */
      38:
      39: spawn(path, name, flag, cont_code, err_code, errbuf)
      40:     char        *path;
      41:     char        *name;
      42:     char        *flag;
      43:     int     cont_code;
      44:     int     err_code;
      45:     char        *errbuf;
      46: {
      47:     char        line[NNTP_STRLEN];
      48:     register char   *cp;
      49:     int     i, fd;
      50:     int     fds[2];
      51:     int     pid, npid;
      52:     int     exit_status;
      53: #ifdef XFER_TIMEOUT
      54:     int     xfer_timeout();
      55:     int     (*otimeout)();
      56: #endif
      57: #ifdef USG
      58:     int     status;
      59: #else not USG
      60:     union wait  status;
      61: #endif not USG
      62:     register FILE   *fp;
      63:
      64:     (void) strcpy(tempfile, "/tmp/rpostXXXXXX");
      65:     (void) mktemp(tempfile);
      66:
      67:     fp = fopen(tempfile, "w");
      68:     if (fp == NULL) {
      69:         printf("%d Cannot create temporary file.\r\n", err_code);
      70:         (void) fflush(stdout);
      71:         return (0);
      72:     } else {
      73:         printf("%d Ok\r\n", cont_code);
      74:         (void) fflush(stdout);
      75:     }
      76:
      77: #ifdef XFER_TIMEOUT
      78:     xfer_lines = old_xfer_lines = 0;
      79:     otimeout = signal(SIGALRM, xfer_timeout);
      80:     (void) alarm(XFER_TIMEOUT);
      81: #endif
      82:
      83:     while (fgets(line, sizeof(line), stdin) != NULL) {
      84: #ifdef XFER_TIMEOUT
      85:         xfer_lines++;
      86: #endif
      87:         if ((cp = index(line, '\r')) != NULL)
      88:             *cp = '\0';
      89:         else if ((cp = index(line, '\n')) != NULL)
      90:             *cp = '\0';
      91:
      92:         if (line[0] == '.' && line[1] == '\0')
      93:             break;
      94:
      95:         if (line[0] == '.')
      96:             fputs(line+1, fp);
      97:         else
      98:             fputs(line, fp);
      99:         putc('\n', fp);
     100:     }
     101:     (void) fclose(fp);
     102:
     103: #ifdef XFER_TIMEOUT
     104:     (void) alarm(0);
     105:     (void) signal(SIGALRM, otimeout);
     106: #endif
     107:
     108:     /* See if the connection got closed somehow... */
     109:
     110:     if (line[0] != '.' && line[1] != '\0') {
     111:         (void) unlink(tempfile);
     112: #ifdef SYSLOG
     113: # ifdef LOG
     114:         syslog(LOG_ERR, "%s spawn: EOF before period on line by itself",
     115:             hostname);
     116: # else
     117:         syslog(LOG_ERR, "spawn: EOF before period on line by itself");
     118: # endif
     119: #endif
     120:         return (0);
     121:     }
     122:
     123: #ifdef POSTER
     124:     (void) chown(tempfile, uid_poster, gid_poster);
     125: #endif
     126:
     127:     /* Set up a pipe so we can see errors from rnews */
     128:
     129:     if (pipe(fds) < 0) {
     130: #ifdef SYSLOG
     131:         syslog(LOG_ERR, "spawn: pipe: %m");
     132: #endif
     133:         (void) unlink(tempfile);
     134:         return (-1);
     135:     }
     136:
     137:     /*
     138: 	 * Ok, now we have the article in "tempfile".  We
     139: 	 * should be able to fork off, close fd's 0 to 31 (or
     140: 	 * whatever), open "tempfile" for input, thus making
     141: 	 * it stdin, and then execl the inews.  We think.
     142: 	 */
     143:
     144:     pid = vfork();
     145:     if (pid == 0) {     /* We're in child */
     146: #ifdef POSTER
     147:         (void) setuid(uid_poster);
     148:         (void) setgid(gid_poster);
     149: #endif
     150:
     151:         /* Set up stdout and stderr for child */
     152:
     153:         if (fds[1] != 1) {
     154:             (void) dup2(fds[1], 1);
     155:             (void) close(fds[1]);
     156:         }
     157:         (void) dup2(1, 2);
     158:
     159:         for (i = 3; i < 10; ++i) /* XXX but getdtablesize is too big */
     160:             (void) close(i);
     161:
     162:         fd = open(tempfile, O_RDONLY);
     163:         if (fd != 0) {
     164:             (void) dup2(fd, 0);
     165:             (void) close(fd);
     166:         }
     167:
     168:         execl(path, name, flag, (char *) NULL);
     169:         fprintf(stderr, "spawn: execl ");
     170:         perror(path);
     171:         _exit(-1);  /* Error */
     172:     } else {
     173:         (void) close(fds[1]);
     174:         fp = fdopen(fds[0], "r");
     175:         if (fp == NULL) {
     176:             printf("%d Cannot fdopen %s pipe\r\n", err_code, path);
     177:             (void) fflush(stdout);
     178: #ifdef SYSLOG
     179:             syslog(LOG_ERR, "spawn: pipe: %m");
     180: #endif
     181:             (void) unlink(tempfile);
     182:             return (0);
     183:         }
     184:
     185:         if (errbuf)
     186:             *errbuf = '\0';
     187:
     188:         while (fgets(line, sizeof (line), fp) != NULL) {
     189:             if (line[0] != '\n') {
     190:                 if (errbuf) {
     191:                     if (cp = index(line, '\n'))
     192:                         *cp = '\0';
     193:                     (void) strcat(errbuf, line);
     194:                     (void) strcat(errbuf, "\\");
     195:                 }
     196: #ifdef SYSLOG
     197:                 syslog(LOG_ERR, "%s: %s", path, line);
     198: #endif
     199:             }
     200:         }
     201:
     202:         while ((npid = wait(&status)) > 0)
     203:             if (npid == pid) {
     204: #ifdef USG
     205:                 exit_status = (status >> 8) & 0xff;
     206: #else not USG
     207:                 exit_status = status.w_T.w_Retcode;
     208: #endif not USG
     209:                 break;
     210:             }
     211:
     212:         (void) fclose(fp);
     213:         (void) unlink(tempfile);
     214:         (void) fflush(stdout);
     215:         if (npid < 0) {
     216: #ifdef SYSLOG
     217:             syslog(LOG_ERR, "spawn: wait pid %d: %m", pid);
     218: #endif
     219:             return (-1);
     220:         }
     221:
     222: #ifdef SYSLOG
     223:         if (exit_status != 0)
     224:             syslog(LOG_ERR, "spawn: %s exit status %d",
     225:                 path, exit_status);
     226: #endif
     227:
     228:         return (exit_status ? -1 : 1);
     229:     }
     230: }
     231:
     232: #ifdef XFER_TIMEOUT
     233:
     234: xfer_timeout()
     235: {
     236:     if (old_xfer_lines < xfer_lines) {
     237:         old_xfer_lines = xfer_lines;
     238:         (void) alarm(XFER_TIMEOUT);
     239:         return;
     240:     }
     241:
     242:     /* Timed out. */
     243:
     244:     printf("%d timeout after %d seconds, closing connection.\r\n",
     245:         ERR_FAULT, XFER_TIMEOUT);
     246:     fflush(stdout);
     247:
     248: #ifdef LOG
     249:     syslog(LOG_ERR, "%s transfer_timeout", hostname);
     250: #endif LOG
     251:
     252:     (void) unlink(tempfile);
     253:
     254:     exit(1);
     255: }
     256:
     257: #endif XFER_TIMEOUT

#### Defined functions

spawn defined in line 39; used 2 times

- in /usr/src/new/nntp/server/ihave.c line 46
- in /usr/src/new/nntp/server/post.c line 42

xfer_timeout defined in line 234; used 2 times

- in line 54, 79

#### Defined variables

old_xfer_lines defined in line 13; used 3 times

- in line 78, 236-237(2)

sccsid defined in line 2; never used
tempfile defined in line 16; used 10 times

- in line 64-67(3), 111, 124, 133, 162, 181, 213, 252

xfer_lines defined in line 12; used 4 times

- in line 78, 85, 236-237(2)

Last modified: 1988-02-07 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1642 |