Annotation of 43BSD/contrib/notes/src/misc.c, revision 1.1.1.1

1.1       root        1: #include <errno.h>
                      2: #include <sys/param.h>
                      3: #include "parms.h"
                      4: #include "structs.h"
                      5: #include <signal.h>                                    /* signal processing */
                      6: #include <ctype.h>
                      7: #ifdef SIGCHLD
                      8: #include <sys/wait.h>                                  /* for child status */
                      9: #endif SIGCHLD
                     10: 
                     11: #ifdef RCSIDENT
                     12: static char rcsid[] = "$Header: misc.c,v 1.7.0.5 85/10/06 01:41:01 notes Rel $";
                     13: #endif RCSIDENT
                     14: 
                     15: #define                LOCKTRY         10                      /* number of shots at grabbing */
                     16: #define                FORKTRY         10                      /* tries at forking */
                     17: 
                     18: /*
                     19:  * dounix(charstring, flag) will execute that character string as a shell command
                     20:  * stolen from shell, though this one catches more signals.
                     21:  *
                     22:  *     Depending on the RUNSUID flag the routine sets things back to
                     23:  *     the users group or uid. Early versions were setuid and newer
                     24:  *     versions only run setgid.  Don't get confused by the "hisuid"
                     25:  *     argument: it really means "reset to his permissions".
                     26:  *     R. Kolstad -- 11/2/80
                     27:  *     modified: R. Essick January 1982, to clean up some signal processing
                     28:  *
                     29:  */
                     30: 
                     31: #if    defined(SIGCHLD)
                     32: static int  kidpid;                                    /* passed by kidwatch() */
                     33: static  union wait kidstatus;
                     34: #endif defined(SIGCHLD)
                     35: 
                     36: 
                     37: #ifndef        FASTFORK
                     38: dounix (linebuf, hisuid, ttymode)
                     39: char    linebuf[];
                     40: #else
                     41: dounix (hisuid, ttymode, arg0, arg1, arg2, arg3, arg4)
                     42: char   *arg0,
                     43:        *arg1,
                     44:        *arg2,
                     45:        *arg3,
                     46:        *arg4;
                     47: #endif
                     48: {
                     49:     register    pid,
                     50:                 forktry,
                     51:                 rpid;
                     52:     int     (*p) (),
                     53:             (*q) (),
                     54:             (*r) ();
                     55: #if    defined(SIGTSTP)
                     56:     int     (*s) ();
                     57: #endif defined(SIGTSTP)
                     58: #if    defined(SIGCHLD)
                     59:     int     (*t) ();
                     60:     extern int  watchkid ();                           /* catch stopped kids */
                     61: #endif defined(SIGCHLD)
                     62:     int     retcode;
                     63: 
                     64: 
                     65:     if (ttymode)
                     66:        ttystop ();                                     /* give back to normal mode */
                     67:     pid = 0;                                           /* satisfy init conditions */
                     68:     forktry = 0;                                       /* init the counter */
                     69:     while (pid <= 0 && ++forktry < FORKTRY)
                     70:     {
                     71:        if ((pid = fork ()) == 0)
                     72:        {
                     73:            uncatchem ();                               /* reset this process signals */
                     74:                                                        /* if user can get his hands on it */
                     75:            if (hisuid)                                 /* only set uid if giving shell */
                     76: #ifdef RUNSUID
                     77:                setuid (globuid);                       /* give him his uid */
                     78: #else
                     79:            setgid (getgid ());                         /* his group */
                     80: #endif RUNSUID
                     81:            for (rpid = 3; rpid < NOFILE; rpid++)       /* close extra files */
                     82:                close (rpid);
                     83: 
                     84: #ifndef        FASTFORK
                     85:            if (linebuf == 0)
                     86:                execl (hisshell, hisshell, 0);
                     87:            else
                     88:                execl (DFLTSH, "sh", "-c", linebuf, 0);
                     89:            printf ("Rats -- Couldn't load %s\n", DFLTSH);
                     90: #else
                     91:            if (arg0 == 0)
                     92:                execlp (hisshell, hisshell, 0);
                     93:            else
                     94:                execlp (arg0, arg0, arg1, arg2, arg3, arg4);
                     95:            printf ("Rats - Couldn't load %s\n", arg0);
                     96: #endif
                     97: 
                     98:            _exit (BAD);                                /* if exec fails .. */
                     99:        }
                    100:        if (pid <= 0)                                   /* if fork failed */
                    101:            sleep (2);                                  /* wait a bit */
                    102:     }
                    103:     if (pid > 0)                                       /* only if have son */
                    104:     {
                    105:        p = signal (SIGHUP, SIG_IGN);
                    106:        q = signal (SIGINT, SIG_IGN);
                    107:        r = signal (SIGQUIT, SIG_IGN);
                    108: #if    defined(SIGTSTP)
                    109:        s = signal (SIGTSTP, SIG_DFL);
                    110: #endif defined(SIGTSTP)
                    111: #if    defined(SIGCHLD)
                    112:        t = signal (SIGCHLD, watchkid);                 /* if he signals */
                    113: #endif defined(SIGCHLD)
                    114:        while ((rpid = wait (&retcode)) != pid && rpid != -1);
                    115:        if (rpid == -1)
                    116:        {
                    117: #if    defined(SIGCHLD)
                    118: /*
                    119:  *     watchkid() might have sucked down the status of the terminated
                    120:  *     child, so we load whatever value it left for us in kidstatus
                    121:  *     (provided that kidpid was ok)
                    122:  */
                    123:            if (pid == kidpid)                          /* the one we wanted */
                    124:                retcode = kidstatus.w_status;           /* from watchkid() */
                    125:            else
                    126:                retcode = 1 << 8;                       /* make an error */
                    127: #else
                    128: /*
                    129:  *     normal case, if the wait() failed for some reason we say that it
                    130:  *     is an error.
                    131:  */
                    132:            retcode = 1 << 8;                           /* indicates error  */
                    133: #endif defined(SIGCHLD)
                    134:        }
                    135:        signal (SIGHUP, p);
                    136:        signal (SIGINT, q);
                    137:        signal (SIGQUIT, r);
                    138: #if    defined(SIGTSTP)
                    139:        signal (SIGTSTP, s);
                    140: #endif defined(SIGTSTP)
                    141: #if    defined(SIGCHLD)
                    142:        signal (SIGCHLD, t);
                    143: #endif defined(SIGCHLD)
                    144:     }
                    145:     else
                    146:        retcode = -1;                                   /* some sort of error */
                    147:     if (ttymode)
                    148:        ttystrt ();                                     /* back into raw mode */
                    149:     return retcode >> 8;                               /* hand him the completion code */
                    150: }
                    151: 
                    152: #if    defined(SIGCHLD)
                    153: /*
                    154:  *     watchkid()
                    155:  *
                    156:  *     called when we receive a SIGCHLD signal, indicating that a child's
                    157:  *     status has changed.  This routine looks via wait3() to see if
                    158:  *     the children have merely been suspended.  If so, it stops itself
                    159:  *     so that it's parent can decide what to do.
                    160:  *
                    161:  *     This catches problems with programs like vi which run in raw mode
                    162:  *     and catch ^z as a character. They later try to signal the entire
                    163:  *     process group but are unable to signal the notes process since it
                    164:  *     has a different effective uid. By watching the SIGCHLD signal, we
                    165:  *     get notification when the vi process has stopped and we can stop
                    166:  *     ourselves. 
                    167:  *                             Ray Essick,     Augst 22, 1984
                    168:  */
                    169: static int  watchkid (sig)
                    170: int     sig;
                    171: {
                    172: 
                    173:     kidpid = wait3 (&kidstatus, WUNTRACED | WNOHANG, 0);/* get status */
                    174:     if (kidpid == 0)                                   /* nothing to report */
                    175:        return 0;                                       /* get out */
                    176:     if (kidpid == (-1))                                        /* no children at all */
                    177:        return 0;                                       /* get out */
                    178:     if (WIFSTOPPED (kidstatus))                                /* stopped himself */
                    179:     {
                    180:        kill (getpid (), SIGTSTP);                      /* stop myself */
                    181:     }
                    182: }
                    183: #endif defined(SIGCHLD)
                    184: 
                    185: /*
                    186:  *     If the condition is TRUE (non-zero) abort the program.
                    187:  *
                    188:  *     Print the supplied message and halt.
                    189:  *     Leave an optional core dump for debugging later.
                    190:  *
                    191:  *     Ray Essick 10/23/80
                    192:  */
                    193: 
                    194: x (cond, p) char   *p;
                    195: {
                    196:     if (cond == 0)
                    197:        return;                                         /* didnt fail */
                    198: 
                    199:     perror ("notes");
                    200:     fprintf (stderr, "Fatal Internal Notesfile Error: %s\n", p);
                    201:     ttystop ();                                                /* back to normal */
                    202: 
                    203: 
                    204: #ifdef DUMPCORE
                    205:     if (chdir (Mstdir) < 0)                            /* go to known place */
                    206:        exit (BAD);                                     /* drop out */
                    207:     if (chdir (UTILITY) < 0)
                    208:        exit (BAD);                                     /* drop out */
                    209:     if (chdir (DUMPCORE) < 0)                          /* writeable to all */
                    210:        exit (BAD);                                     /* drop out */
                    211: #ifdef RUNSUID
                    212:     setuid (globuid);                                  /* won't dump if euid != uid */
                    213: #else
                    214:     setgid (getgid ());                                        /* no gift groups */
                    215: #endif RUNSUID
                    216: #endif DUMPCORE
                    217: 
                    218: #ifdef NFMAINT
                    219: /*
                    220:  *     This code is kind of risky.  If the NFMAINT notesfile ever
                    221:  *     gets trashed and starts calling this routine, look out because
                    222:  *     it will recursively fail. This is the unfortunate byproduct
                    223:  *     of the fact that the "x" routine doesn't know what the 
                    224:  *     current notesfile is.
                    225:  */
                    226:     {
                    227:        char    pbuf[512];                              /* hold message */
                    228:        char    pbuf2[128];                             /* and title */
                    229:        char    pbuf3[256];                             /* core image */
                    230:        char   *tail;                                   /* end of invocation */
                    231: 
                    232:        sprintf (pbuf2, "%s: aborted", Invokedas);
                    233:        sprintf (pbuf, "Program:\t%s\nMessage:\t%s\n\nerrno:\t\t%d  (%s)\n",
                    234:                Invokedas, p, errno,
                    235:                errno >= sys_nerr ? "Unknown error code" : sys_errlist[errno]);
                    236: #ifdef DUMPCORE
                    237:        if ((tail = rindex (Invokedas, '/')) == NULL)   /* pathname? */
                    238:            tail = Invokedas;                           /* simple invocation */
                    239:        else
                    240:            tail++;                                     /* strip the slash */
                    241:        sprintf (pbuf3, "%s/%s/%s/%s", Mstdir, UTILITY, DUMPCORE, tail);
                    242:        nfabort (NFMAINT, pbuf, pbuf2, pbuf3, BAD);     /* log & abort */
                    243: #else  ! DUMPCORE
                    244:        nfcomment (NFMAINT, pbuf, pbuf2, 0, 0);         /* actual insertion */
                    245: #endif DUMPCORE
                    246:     }
                    247: #endif NFMAINT
                    248: 
                    249: /*
                    250:  *     Handle the exit if NFMAINT is undefined.
                    251:  */
                    252: 
                    253: #ifdef DUMPCORE
                    254:     abort ();                                          /* dump in "core" */
                    255: #else
                    256:     exit (BAD);                                                /* for production */
                    257: #endif DUMPCORE
                    258: }
                    259: 
                    260: /*
                    261:  *     lock creates a lock file, or waits until it can create the lock.
                    262:  *     lock files are of the form lock#  where # is a character passed
                    263:  *     to the routine.
                    264:  *
                    265:  *     Rob Kolstad     10/20/80
                    266:  *     modified: rbe December 1981 to add full path name for lock file 
                    267:  */
                    268: 
                    269: locknf (io, c)
                    270: struct io_f *io;
                    271: char    c;
                    272: {
                    273:     register int    i,
                    274:                     holderr,
                    275:                     trys;
                    276:     char    p[WDLEN];
                    277: 
                    278:     sprintf (p, "%s/%s/%c%s", Mstdir, LOCKS, c, io -> nf);
                    279:                                                        /* generate file name */
                    280:     trys = LOCKTRY;                                    /* set him up */
                    281:     while ((i = creat (p, 0)) < 0)
                    282:     {
                    283:        if (trys-- == 0)
                    284:        {
                    285:            holderr = errno;                            /* before it's abused */
                    286:            fprintf (stderr, "lock %c (%s) permanently locked - consult a guru\n",
                    287:                    c, io -> nf);
                    288: #ifdef NFMAINT
                    289:            if (strcmp (NFMAINT, io -> nf))             /* avoid loops */
                    290:            {
                    291:                char    pbuf[256];                      /* for error logging */
                    292:                char    tbuf[256];                      /* title */
                    293:                sprintf (pbuf,
                    294:                        "lock %c failed for %s,\nerrno = %d (%s)\nProgram = %s\n",
                    295:                        c, io -> fullname, holderr, sys_errlist[holderr],
                    296:                        Invokedas);
                    297:                sprintf (tbuf, "%s: locked (%c)", io -> nf, c);
                    298:                nfcomment (NFMAINT, pbuf, tbuf, 0, 0);
                    299:            }
                    300: #endif NFMAINT
                    301:            ttystop ();
                    302:            exit (BAD);
                    303:        }
                    304:        sleep (2);                                      /* guarantee at least 1 */
                    305:     }
                    306:     ignoresigs++;                                      /* critical section */
                    307: /*
                    308:  *     could be above getting the lock, but wanted to be able to suspend
                    309:  *     while getting the lock.  The interuptable window is very small
                    310:  */
                    311:     close (i);
                    312: }
                    313: 
                    314: /*
                    315:  *     unlock takes the same arguements as the lock routine, and it
                    316:  *     will remove the corresponding lock file
                    317:  *
                    318:  *     Rob Kolstad 10/20/80
                    319:  *     modified: rbe December 1981 to add full path name for lock name
                    320:  */
                    321: 
                    322: unlocknf (io, c)
                    323: struct io_f *io;
                    324: char    c;
                    325: {
                    326:     char    p[WDLEN];
                    327: 
                    328:     sprintf (p, "%s/%s/%c%s", Mstdir, LOCKS, c, io -> nf);
                    329:                                                        /* generate file name */
                    330:     x (unlink (p) < 0, "unlock: unlink lock");
                    331:     ignoresigs--;                                      /* no longer critical */
                    332: }
                    333: 
                    334: /*
                    335:  *     glock creates a lock file, or waits until it can create the lock.
                    336:  *     lock files are of the form lock#  where # is a character passed
                    337:  *     to the routine.
                    338:  *             This lock file is a GLOBAL lock - across all notefiles
                    339:  *
                    340:  *     taken from lock routine above by R. Essick December 1981
                    341:  */
                    342: 
                    343: glocknf (io, c)
                    344: struct io_f *io;                                       /* unused in this routine */
                    345: char    c;
                    346: {
                    347:     register int    i,
                    348:                     holderr,
                    349:                     trys;
                    350:     char    p[WDLEN];
                    351: 
                    352:     sprintf (p, "%s/%s/%c", Mstdir, LOCKS, c);         /* generate file name */
                    353:     trys = LOCKTRY;
                    354:     while ((i = creat (p, 0)) < 0)
                    355:     {
                    356:        if (trys-- == 0)
                    357:        {
                    358:            holderr = errno;                            /* before it's abused */
                    359:            fprintf (stderr, "lock%c combo lost - consult your local guru\n", c);
                    360: #ifdef NFMAINT
                    361:            if (strcmp (NFMAINT, io -> nf))             /* don't loop on self */
                    362:            {
                    363:                char    pbuf[256];                      /* for error logging */
                    364:                char    pbuf2[256];
                    365:                sprintf (pbuf,
                    366:                        "glock %c failed for %s, errno = %d (%s)\nProgram = %s\n",
                    367:                        c, io -> fullname, holderr, sys_errlist[holderr],
                    368:                        Invokedas);
                    369:                sprintf (pbuf2, "Frozen Global Lock (%c)", c);
                    370:                nfcomment (NFMAINT, pbuf, pbuf2, 0, 0);
                    371:            }
                    372: #endif NFMAINT
                    373:            ttystop ();
                    374:            exit (BAD);
                    375:        }
                    376:        sleep (2);                                      /* is there a smaller time interval */
                    377:     }
                    378:     close (i);
                    379: }
                    380: 
                    381: /*
                    382:  *     gunlock takes the same arguements as the lock routine, and it
                    383:  *     will remove the corresponding lock file
                    384:  *             This is GLOBAL locking - across all notefiles
                    385:  *
                    386:  *     copy of code from unlock, with minor changes
                    387:  *     Ray Essick      December 1981
                    388:  */
                    389: 
                    390: gunlocknf (io, c)
                    391: struct io_f *io;                                       /* not used by this routine */
                    392: char    c;
                    393: {
                    394:     char    p[WDLEN];
                    395: 
                    396:     sprintf (p, "%s/%s/%c", Mstdir, LOCKS, c);         /* make the file name */
                    397:     x (unlink (p) < 0, "gunlock: unlink lock");
                    398: }
                    399: 
                    400: /*
                    401:  * length tells us max(length of string, 1)
                    402:  */
                    403: len (p, n) char *p;
                    404: {
                    405:     int     i;
                    406:     i = n;
                    407:     p += n;
                    408:     while (*--p == ' ' && --i)
                    409:        if (i == 0)
                    410:            i = 1;
                    411:     return i;
                    412: }
                    413: 
                    414: /*
                    415:  *     shell - give the user a shell
                    416:  *     this includes:
                    417:  *     1) changing to the directory where he came in from
                    418:  *     2) giving him a shell
                    419:  *     3) return to the notefile directory
                    420:  *
                    421:  *     original author: Ray Essick may 29, 1981
                    422:  *
                    423:  */
                    424: 
                    425: gshell ()
                    426: {
                    427:     printf ("\n");
                    428: #ifndef        FASTFORK
                    429:     dounix (0, 1, 1);                                  /* give him his shell */
                    430: #else
                    431:     dounix (1, 1, 0, 0, 0, 0, 0);
                    432: #endif
                    433:     return 0;
                    434: }
                    435: 
                    436: /*     copydate merely moves a when_f structure from 'from' to 'to' */
                    437: /*     ray essick - 20-nov-1981        */
                    438: 
                    439: copydate (from, to)
                    440: struct when_f  *from,
                    441:                *to;
                    442: {
                    443:     *to = *from;                                       /* use block move */
                    444: }
                    445: 
                    446: /*     strmove - copy a null terminated string to another */
                    447: /*     returns the count of characters moved, this count includes the */
                    448: /*     null terminator.. */
                    449: /*     r. essick 20-nov-81 */
                    450: 
                    451: strmove (p, q)
                    452: char   *p,
                    453:        *q;                                             /* from p to q */
                    454: {
                    455:     int     count;
                    456:     register char  *pp,
                    457:                    *qq;
                    458: 
                    459:     count = 0;                                         /* start with no characters moved */
                    460:     pp = p;
                    461:     qq = q;                                            /* use registers for speed */
                    462:     while (*qq++ = *pp++)
                    463:        count++;
                    464:     return count;                                      /* return count of characters moved */
                    465:                                                        /* don't include the terminator */
                    466: }
                    467: 
                    468: /*     copyauth(from, to) struct auth_f *from,*auth
                    469:  *     copys author from from to to
                    470:  *     Ray Essick December 1981
                    471:  *
                    472:  *     SHOULD USE STRUCTURE ASSIGNMENT IN ALL PLACES THAT CALL THIS
                    473:  */
                    474: copyauth (from, to)
                    475: struct auth_f  *from,
                    476:                *to;
                    477: {
                    478: 
                    479:     strncpy (to -> aname, from -> aname, NAMESZ);      /* author name */
                    480:     strncpy (to -> asystem, from -> asystem, HOMESYSSZ);/* home machine */
                    481:     to -> aid = from -> aid;                           /* and user id */
                    482: }
                    483: 
                    484: /*     listget, listconv - parse a list of numbers. 
                    485:  *     this is all taken ( sort of ) from Rob Kolstad's getpg
                    486:  *     program 
                    487:  */
                    488: 
                    489: listget (buf, ptr, start, finish)
                    490: char    buf[];
                    491: int    *ptr,
                    492:        *start,
                    493:        *finish;
                    494: {
                    495:     if ((buf[*ptr] < '0' || buf[*ptr] > '9') && buf[*ptr] != ' ')
                    496:     {
                    497:        return 0;                                       /* end of this list */
                    498:     }
                    499:     *start = listconv (buf, ptr);                      /* get the first */
                    500:     *finish = *start;                                  /* default to single */
                    501:     if (buf[*ptr] == '-')
                    502:     {
                    503:        ++(*ptr);                                       /* trash that separator */
                    504:        *finish = listconv (buf, ptr);                  /* grab second */
                    505:        ++(*ptr);                                       /* bump past delimiter */
                    506:        return 2;                                       /* parsed 2 arguements */
                    507:     }
                    508:     else
                    509:     {
                    510:        if (buf[*ptr] != '\0')
                    511:            ++(*ptr);                                   /* dump delimiter */
                    512:        return 1;
                    513:     }
                    514: }
                    515: 
                    516: listconv (buf, ptr)
                    517: char    buf[];
                    518: int    *ptr;
                    519: {
                    520:     int     i;
                    521:     i = 0;
                    522:     while (buf[*ptr] == ' ')
                    523:        ++(*ptr);
                    524:     while (buf[*ptr] >= '0' && buf[*ptr] <= '9')
                    525:     {
                    526:        i = 10 * i + buf[*ptr] - '0';
                    527:        ++(*ptr);                                       /* bump him */
                    528:     }
                    529:     return (i);
                    530: }
                    531: 
                    532: /*     tolcase - check to see if upper case, and convert to lcase */
                    533: /*     R. Essick       Feb 1982 */
                    534: tolcase (c)
                    535: char    c;
                    536: {
                    537:     if (isascii (c) && isupper (c))
                    538:        return (tolower (c));                           /* to lower case */
                    539:     return (c);                                                /* leave as is */
                    540: }
                    541: 
                    542: /*
                    543:  *     Date printing stuff.
                    544:  *
                    545:  *     CHANGE TO CTIME(III) FORMAT EVENTUALLY
                    546:  */
                    547: 
                    548: char   *mnames[13] =                                   /* so indexes work right */
                    549: {
                    550:     "???", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
                    551:     "Sep", "Oct", "Nov", "Dec"
                    552: };
                    553: 
                    554: sprdate (w, str) struct when_f *w;
                    555: char   *str;
                    556: {
                    557:     char   *m;
                    558:     int     h,
                    559:             i,
                    560:             j;                                         /* temps to print 0's or funny strings */
                    561:     m = "am";
                    562:     h = w -> w_hours;
                    563:     if (h >= 12)
                    564:        m = "pm";
                    565:     if (h == 0)
                    566:        h = 12;
                    567:     if (h > 12)
                    568:        h -= 12;
                    569:     i = w -> w_mins / 10;
                    570:     j = w -> w_mins % 10;                              /* get those leading zeroes */
                    571:     sprintf (str, "%2d:%d%d %2s  %3s %2d, %4d", h, i, j, m, mnames[w -> w_month], w -> w_day, w -> w_year);
                    572:                                                        /* sprintf puts it into a string */
                    573: }
                    574: 
                    575: prdate (zdate) struct when_f   *zdate;
                    576: {
                    577:     char    line[DATELEN];
                    578: 
                    579:     sprdate (zdate, line);                             /* format it */
                    580:     printf ("%s", line);                               /* and print it */
                    581: }
                    582: 
                    583: /*
                    584:  *     Saves a string with malloc() and returns a pointer
                    585:  *     to where it wound up.  Useful for building lists of
                    586:  *     stuff.
                    587:  *
                    588:  *     Courtesy of Lou Salkind & Rick Spickelmier.
                    589:  */
                    590: 
                    591: 
                    592: char   *strsave (s)
                    593: char   *s;
                    594: {
                    595:     char   *p;
                    596:     extern char *malloc ();
                    597: 
                    598:     p = malloc (strlen (s) + 1);
                    599:     strcpy (p, s);
                    600:     return (p);
                    601: }
                    602: 
                    603: /*
                    604:  *     substr(a,b)     see if A is a substring of B
                    605:  *
                    606:  *     uses: strlen.
                    607:  */
                    608: 
                    609: substr (a, b)
                    610: char   *a;
                    611: char   *b;
                    612: {
                    613:     register char   first;
                    614:     register int    length;                            /* length of a */
                    615:     register int    count;                             /* max checks */
                    616: 
                    617:     first = *a;                                                /* get first */
                    618:     length = strlen (a);                               /* for strncmp */
                    619:     count = strlen (b) - length + 1;                   /* max checks */
                    620:     while (count-- > 0)                                        /* can try */
                    621:     {
                    622:        if (*b == first && !strncmp (a, b, length))
                    623:            return (1);                                 /* is a substring */
                    624:        b++;                                            /* on to next */
                    625:     }
                    626:     return (0);                                                /* not a substring */
                    627: }
                    628: 
                    629: /*
                    630:  *     routine to process a string and remove any
                    631:  *     nasties like control characters and escape codes.
                    632:  */
                    633: 
                    634: int     strclean (p)
                    635: char   *p;
                    636: {
                    637:     if (p == (char *) NULL)
                    638:        return 0;
                    639:     if (*p == '\0')
                    640:        return 0;
                    641:     do
                    642:     {
                    643:        if (!isascii (*p) || iscntrl (*p))
                    644:            *p = '_';                                   /* kill controls */
                    645:     } while (*++p != '\0');
                    646:     return (0);
                    647: }

unix.superglobalmegacorp.com

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