Annotation of researchv8dc/cmd/upas/common/subrs.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     subroutines that weren't worth their own files
                      3:  */
                      4: #include <stdio.h>
                      5: #include <signal.h>
                      6: #include <sys/param.h>
                      7: #include "mail.h"
                      8: #include "string.h"
                      9: 
                     10: /* configuration */
                     11: #define FRWRD  "Forward to "
                     12: #define PIPE   "Pipe to "
                     13: #define WHOAMI "/etc/whoami"           /* file containing system name */
                     14: #define MAILROOT "/usr/spool/mail/"    /* root of mail system */
                     15: #define UPASROOT "/usr/lib/upas/"      /* root of upas system */
                     16: 
                     17: /* imported */
                     18: int rmail;             /* true if started as rmail (init if undefined) */
                     19: int onatty;            /* true if on a tty (init if undefined) */
                     20: extern unsigned int alarm();
                     21: 
                     22: /* return a pointer to last element of a pathname */
                     23: extern char *
                     24: basename(file)
                     25: char *file;
                     26: {
                     27:        char *base;
                     28:        char *strrchr();
                     29: 
                     30:        if ((base = strrchr(file, '/')) != 0)
                     31:                base++;         /* past '/' */
                     32:        else
                     33:                base = file;
                     34:        return (base);
                     35: }
                     36: 
                     37: /* get the next whitespace delimited token from a string */
                     38: extern char *
                     39: getarg(s, p)      /* copy p... into s, update p */
                     40: register char *s, *p;
                     41: {
                     42:        while (*p == ' ' || *p == '\t')
                     43:                p++;
                     44:        if (*p == '\n' || *p == '\0')
                     45:                return(NULL);
                     46:        while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0')
                     47:                *s++ = *p++;
                     48:        *s = '\0';
                     49:        return(p);
                     50: }
                     51: 
                     52: /* a path to a mail file */
                     53: extern char *
                     54: mailpath(relp)
                     55:        char *relp;             /* relative path name */
                     56: {
                     57:        static char pathname[128];
                     58: 
                     59:        if (*relp == '/')
                     60:                *pathname = '\0';
                     61:        else
                     62:                (void)strcpy(pathname, MAILROOT);
                     63:        (void)strcat(pathname, relp);
                     64:        return pathname;
                     65: }
                     66: 
                     67: /* a path to a special upas file */
                     68: extern char *
                     69: upaspath(relp)
                     70:        char *relp;             /* relative path name */
                     71: {
                     72:        static char pathname[128];
                     73: 
                     74:        if (*relp == '/')
                     75:                *pathname = '\0';
                     76:        else
                     77:                (void)strcpy(pathname, UPASROOT);
                     78:        (void)strcat(pathname, relp);
                     79:        return pathname;
                     80: }
                     81: 
                     82: /* get the system's name */
                     83: extern char *
                     84: getsysname()
                     85: {
                     86:        int f;
                     87:        char *strchr();
                     88:        static char wsysname[33];
                     89: 
                     90:        f = open(WHOAMI, 0);
                     91:        if (f>=0) {
                     92:                wsysname[0] = '\0';
                     93:                read(f, wsysname, 32);
                     94:                if (strchr(wsysname, '\n')) {
                     95:                        *strchr(wsysname, '\n') = '\0';
                     96:                }
                     97:                close(f);
                     98:        }
                     99:        return wsysname;
                    100: }
                    101: 
                    102: /*
                    103:  *     Return:
                    104:  *             0 if no special action is requested
                    105:  *             1 if fowarding (new address in param)
                    106:  *             2 if mail is to be piped to a comand (command in param)
                    107:  */
                    108: extern int
                    109: delivery_status(s, param)
                    110:        char *s, *param;
                    111: {
                    112:        FILE *fp;
                    113:        char fbuf[CMDSIZE], *p, *sp;
                    114:        int rv = MF_NORMAL;
                    115:        extern char *stringin();
                    116: 
                    117: 
                    118:        fp = fopen(s, "r");
                    119:        if(fp == NULL)
                    120:                return MF_NORMAL;
                    121:        fbuf[0] = '\0';
                    122:        fgets(fbuf, sizeof(fbuf), fp);
                    123:        if (p = stringin(FRWRD, fbuf))
                    124:                rv = MF_FORWARD;
                    125:        else if (p = stringin(PIPE, fbuf))
                    126:                rv = MF_PIPE;
                    127:        if (rv != 0) {
                    128:                while (*p == ' ')
                    129:                        p++;
                    130:                sp = param;
                    131:                while (*p && *p!='\n')
                    132:                        *sp++ = *p++;
                    133:                *sp = '\0';
                    134:                if (fgets(fbuf, sizeof(fbuf), fp) != NULL)
                    135:                        rv |= MFEXTRA;
                    136:        }
                    137:        fclose(fp);
                    138:        return (*param != 0) ? rv : MF_NORMAL;
                    139: }
                    140: 
                    141: /*
                    142:  *     Find one string within another.
                    143:  *     Return:  NULL if line doesn't contain str
                    144:  *              a pointer to the first byte following str in line otherwise
                    145:  */
                    146: extern char *
                    147: stringin(str, line)
                    148: char *str, *line;
                    149: {
                    150:        register char *sp, *lp;
                    151: 
                    152:        while (*line) {
                    153:                sp = str;
                    154:                lp = line++;
                    155:                for (;;) {
                    156:                        if (*sp != *lp) {
                    157:                                if (*sp=='\0')
                    158:                                        return(lp);
                    159:                                break;
                    160:                        }
                    161:                        sp++;
                    162:                        lp++;
                    163:                }
                    164:        }
                    165:        return(NULL);
                    166: }
                    167: 
                    168: /* print error and core dump */
                    169: extern int
                    170: panic(s)
                    171:        char *s;
                    172: {
                    173:        fprintf(stderr, "mail: %s\n", s);
                    174:        signal(SIGQUIT, SIG_DFL);
                    175:        kill(getpid(), SIGQUIT);
                    176:        exit(-1);
                    177: }
                    178: 
                    179: /* global to from parsing */
                    180: static char rmtlist[ADDRSIZE];
                    181: 
                    182: /* output a unix header with remote from blurb */
                    183: extern void
                    184: putrfunix(sender, date, sys, fp)
                    185:        char *date, *sys, *sender;
                    186:        FILE *fp;
                    187: {
                    188:        fprintf(fp, "From %s %s%s%s\n", sender, date, REMFROM, sys);
                    189: }
                    190: 
                    191: /* output a unix header */
                    192: extern void
                    193: putunix(sender, date, fp)
                    194:        char *sender, *date;
                    195:        FILE *fp;
                    196: {
                    197:        fprintf(fp, "From %s %s\n", sender, date);
                    198: }
                    199: 
                    200: /* start the unix parse */
                    201: extern void
                    202: initgetunix()
                    203: {
                    204:        rmtlist[0] = '\0';
                    205: }
                    206: 
                    207: /* get/parse unix from line */
                    208: extern int
                    209: getunix(line, sender, date)
                    210:        char *line;     /* line to parse */
                    211:        char *sender;   /* filled by parseline */
                    212:        char *date;     /* filled by parseline */
                    213: {
                    214:        char *rp, *dp, *sp;
                    215: 
                    216:        /* look for a from */
                    217:        if ((sp = stringin(FROM, line))!=NULL
                    218:            || (sp = stringin(ALTFROM, line))!=NULL) {
                    219: 
                    220:                /* do we have a remote from? */
                    221:                if ((rp = stringin(REMFROM, line))!=NULL) {
                    222: 
                    223:                        /* add to remote list */
                    224:                        line[strlen(line)-1] = '\0';
                    225:                        *(rp - (sizeof(REMFROM)-1)) = '\0';
                    226:                        if ((dp = strchr(sp, ' ')) != NULL) {
                    227:                                strcpy(date, dp+1);
                    228:                                *dp = '\0';
                    229:                        }
                    230:                        (void)strcpy(sender, sp);
                    231:                        (void)strcat(rmtlist, rp);
                    232:                        (void)strcat(rmtlist, "!");
                    233:                        return -1;
                    234:                }
                    235:        }
                    236: 
                    237:        /* Not a from line */
                    238:        /* Use what we've found so far */
                    239:        (void)strcat(rmtlist, sender);
                    240:        (void)strcpy(sender, rmtlist);
                    241:        return 0;
                    242: }
                    243: 
                    244: /*
                    245:  *     a paranoid's version of popen 
                    246:  */
                    247: #define        RDR     0
                    248: #define        WTR     1
                    249: 
                    250: static int ppid;
                    251: static int perrfd;
                    252: static char *envp[] = {
                    253:        "IFS=   \n",
                    254:        "PATH=/bin:/usr/bin:/usr/lib/upas",
                    255:        0
                    256: };
                    257: 
                    258: static char perrbuf[CMDSIZE];  /* where to put standard error */
                    259: static int forked;             /* true if we've already forked */
                    260: 
                    261: /* here if popen times out */
                    262: static
                    263: ptimeout()
                    264: {
                    265:        fprintf(stderr, "time out - possbile mail problem\n");
                    266:        exit(1);
                    267: }
                    268: 
                    269: extern FILE *
                    270: popen(cmd, uid, gid)
                    271: char   *cmd;
                    272: int    uid, gid;
                    273: {
                    274:        register i;
                    275:        int p[2], perr[2];
                    276: 
                    277:        /* do mail in background to keep user from getting bored */
                    278:        if (onatty && !rmail && !forked) {
                    279:                switch(fork()) {
                    280:                case 0:
                    281:                        signal(SIGHUP, SIG_IGN);
                    282:                        signal(SIGINT, SIG_IGN);
                    283:                        signal(SIGQUIT, SIG_IGN);
                    284:                        signal(SIGTERM, SIG_IGN);
                    285:                        forked = 1;
                    286:                        break;
                    287:                case -1:
                    288:                        break;
                    289:                default:
                    290:                        exit(0);
                    291:                }
                    292:        }
                    293: 
                    294:        if(pipe(p) < 0)
                    295:                return NULL;
                    296:        if(pipe(perr) < 0) {
                    297:                close(p[RDR]);
                    298:                close(p[WTR]);
                    299:                return NULL;
                    300:        }
                    301:        if((ppid = fork()) == 0) {
                    302:                (void)setgid(gid);
                    303:                (void)setuid(uid);
                    304:                (void)dup2(p[RDR], 0);
                    305:                (void)dup2(perr[WTR], 2);
                    306:                (void)close(1);
                    307:                for (i=3; i<NOFILE; i++)
                    308:                        close(i);
                    309:                execle("/bin/sh", "sh", "-c", cmd, 0, envp);
                    310:                _exit(1);
                    311:        }
                    312:        if(ppid == -1)
                    313:                return NULL;
                    314: 
                    315:        signal(SIGALRM, ptimeout);
                    316:        signal(SIGPIPE, SIG_IGN);
                    317:        alarm(1200);    /* in case of deadly embrace twixt stdin and stderr */
                    318: 
                    319:        close(perr[WTR]);
                    320:        perrfd = perr[RDR];
                    321:        close(p[RDR]);
                    322:        return(fdopen(p[WTR], "w"));
                    323: }
                    324: 
                    325: extern int
                    326: pclose(ptr, perrbuf, perrlen)
                    327: FILE *ptr;
                    328: char *perrbuf;
                    329: unsigned int perrlen;
                    330: {
                    331:        register r, (*hstat)(), (*istat)(), (*qstat)();
                    332:        int status, len, i;
                    333: 
                    334:        fclose(ptr);
                    335:        istat = signal(SIGINT, SIG_IGN);
                    336:        qstat = signal(SIGQUIT, SIG_IGN);
                    337:        hstat = signal(SIGHUP, SIG_IGN);
                    338:        if (perrlen > 0) {
                    339:                for (i = 0; i < perrlen; i += len) {
                    340:                        len = read(perrfd, perrbuf+i, perrlen-i);
                    341:                        if (len <= 0)
                    342:                                break;
                    343:                }
                    344:                perrbuf[i] = '\0';
                    345:        }
                    346:        close(perrfd);
                    347:        alarm(0);       /* see alarm in popen */
                    348:        signal(SIGALRM, SIG_IGN);
                    349:        while((r = wait(&status)) != ppid && r != -1)
                    350:                ;
                    351:        if(r == -1)
                    352:                status = 0;
                    353:        signal(SIGINT, istat);
                    354:        signal(SIGQUIT, qstat);
                    355:        signal(SIGHUP, hstat);
                    356:        return(status);
                    357: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.