Annotation of coherent/g/usr/lib/uucp/tay104/tstuu.c, revision 1.1.1.1

1.1       root        1: /* tstuu.c
                      2:    Test the uucp package on a UNIX system.
                      3: 
                      4:    Copyright (C) 1991, 1992 Ian Lance Taylor
                      5: 
                      6:    This file is part of the Taylor UUCP package.
                      7: 
                      8:    This program is free software; you can redistribute it and/or
                      9:    modify it under the terms of the GNU General Public License as
                     10:    published by the Free Software Foundation; either version 2 of the
                     11:    License, or (at your option) any later version.
                     12: 
                     13:    This program is distributed in the hope that it will be useful, but
                     14:    WITHOUT ANY WARRANTY; without even the implied warranty of
                     15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     16:    General Public License for more details.
                     17: 
                     18:    You should have received a copy of the GNU General Public License
                     19:    along with this program; if not, write to the Free Software
                     20:    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     21: 
                     22:    The author of the program may be contacted at [email protected] or
                     23:    c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
                     24:    */
                     25: 
                     26: #include "uucp.h"
                     27: 
                     28: #if USE_RCS_ID
                     29: const char tstuu_rcsid[] = "$Id: tstuu.c,v 1.1 93/07/30 07:54:26 bin Exp Locker: bin $";
                     30: #endif
                     31: 
                     32: #include "sysdep.h"
                     33: #include "system.h"
                     34: #include "getopt.h"
                     35: 
                     36: #include <stdio.h>
                     37: #include <ctype.h>
                     38: #include <errno.h>
                     39: 
                     40: #if HAVE_SYS_TIMES_H
                     41: #include <sys/times.h>
                     42: #endif
                     43: 
                     44: #if HAVE_SYS_IOCTL_H
                     45: #include <sys/ioctl.h>
                     46: #endif
                     47: 
                     48: #if HAVE_SELECT
                     49: #include <sys/time.h>
                     50: #if HAVE_SYS_SELECT_H
                     51: #include <sys/select.h>
                     52: #endif
                     53: #endif
                     54: 
                     55: #if HAVE_POLL
                     56: #if HAVE_STROPTS_H
                     57: #include <stropts.h>
                     58: #endif
                     59: #if HAVE_POLL_H
                     60: #include <poll.h>
                     61: #endif
                     62: #endif
                     63: 
                     64: #if HAVE_FCNTL_H
                     65: #include <fcntl.h>
                     66: #else
                     67: #if HAVE_SYS_FILE_H
                     68: #include <sys/file.h>
                     69: #endif
                     70: #endif
                     71: 
                     72: #ifndef O_RDONLY
                     73: #define O_RDONLY 0
                     74: #define O_WRONLY 1
                     75: #define O_RDWR 2
                     76: #endif
                     77: 
                     78: #if HAVE_TIME_H && (HAVE_SYS_TIME_AND_TIME_H || ! HAVE_SELECT)
                     79: #include <time.h>
                     80: #endif
                     81: 
                     82: #if HAVE_SYS_WAIT_H
                     83: #include <sys/wait.h>
                     84: #endif
                     85: 
                     86: #if HAVE_UNION_WAIT
                     87: typedef union wait wait_status;
                     88: #else
                     89: typedef int wait_status;
                     90: #endif
                     91: 
                     92: #if HAVE_STREAMS_PTYS
                     93: #include <termio.h>
                     94: extern char *ptsname ();
                     95: #endif
                     96: 
                     97: /* Get definitions for both O_NONBLOCK and O_NDELAY.  */
                     98: 
                     99: #ifndef O_NDELAY
                    100: #ifdef FNDELAY
                    101: #define O_NDELAY FNDELAY
                    102: #else /* ! defined (FNDELAY) */
                    103: #define O_NDELAY 0
                    104: #endif /* ! defined (FNDELAY) */
                    105: #endif /* ! defined (O_NDELAY) */
                    106: 
                    107: #ifndef O_NONBLOCK
                    108: #ifdef FNBLOCK
                    109: #define O_NONBLOCK FNBLOCK
                    110: #else /* ! defined (FNBLOCK) */
                    111: #define O_NONBLOCK 0
                    112: #endif /* ! defined (FNBLOCK) */
                    113: #endif /* ! defined (O_NONBLOCK) */
                    114: 
                    115: #if O_NDELAY == 0 && O_NONBLOCK == 0
                    116:  #error No way to do nonblocking I/O
                    117: #endif
                    118: 
                    119: /* Get definitions for EAGAIN, EWOULDBLOCK and ENODATA.  */
                    120: #ifndef EAGAIN
                    121: #ifndef EWOULDBLOCK
                    122: #define EAGAIN (-1)
                    123: #define EWOULDBLOCK (-1)
                    124: #else /* defined (EWOULDBLOCK) */
                    125: #define EAGAIN EWOULDBLOCK
                    126: #endif /* defined (EWOULDBLOCK) */
                    127: #else /* defined (EAGAIN) */
                    128: #ifndef EWOULDBLOCK
                    129: #define EWOULDBLOCK EAGAIN
                    130: #endif /* ! defined (EWOULDBLOCK) */
                    131: #endif /* defined (EAGAIN) */
                    132: 
                    133: #ifndef ENODATA
                    134: #define ENODATA EAGAIN
                    135: #endif
                    136: 
                    137: /* Make sure we have a CLK_TCK definition, even if it makes no sense.
                    138:    This is in case TIMES_TICK is defined as CLK_TCK.  */
                    139: #ifndef CLK_TCK
                    140: #define CLK_TCK (60)
                    141: #endif
                    142: 
                    143: /* Don't try too hard to get a TIMES_TICK value; it doesn't matter
                    144:    that much.  */
                    145: #if TIMES_TICK == 0
                    146: #undef TIMES_TICK
                    147: #define TIMES_TICK CLK_TCK
                    148: #endif
                    149: 
                    150: #if TIMES_DECLARATION_OK
                    151: extern long times ();
                    152: #endif
                    153: 
                    154: #ifndef SIGCHLD
                    155: #define SIGCHLD SIGCLD
                    156: #endif
                    157: 
                    158: #if 1
                    159: #define ZUUCICO_CMD "login uucp"
                    160: #define UUCICO_EXECL "/bin/login", "login", "uucp"
                    161: #else
                    162: #define ZUUCICO_CMD "su - nuucp"
                    163: #define UUCICO_EXECL "/bin/su", "su", "-", "nuucp"
                    164: #endif
                    165: 
                    166: #if ! HAVE_SELECT && ! HAVE_POLL
                    167:  #error You need select or poll
                    168: #endif
                    169: 
                    170: #if ! HAVE_REMOVE
                    171: #undef remove
                    172: #define remove unlink
                    173: #endif
                    174: 
                    175: /* Buffer chain to hold data read from a uucico.  */
                    176: 
                    177: #define BUFCHARS (512)
                    178: 
                    179: struct sbuf
                    180: {
                    181:   struct sbuf *qnext;
                    182:   int cstart;
                    183:   int cend;
                    184:   char ab[BUFCHARS];
                    185: };
                    186:   
                    187: /* Local functions.  */
                    188: 
                    189: static void umake_file P((const char *zfile, int cextra));
                    190: static void uprepare_test P((boolean fmake, int itest,
                    191:                             boolean fcall_uucico,
                    192:                             const char *zsys));
                    193: static void ucheck_file P((const char *zfile, const char *zerr,
                    194:                           int cextra));
                    195: static void ucheck_test P((int itest, boolean fcall_uucico));
                    196: static RETSIGTYPE uchild P((int isig));
                    197: static int cpshow P((char *z, int bchar));
                    198: static void uchoose P((int *po1, int *po2));
                    199: static long cread P((int o, struct sbuf **));
                    200: static boolean fsend P((int o, int oslave, struct sbuf **));
                    201: static boolean fwritable P((int o));
                    202: static void xsystem P((const char *zcmd));
                    203: static FILE *xfopen P((const char *zname, const char *zmode));
                    204: 
                    205: static char *zDebug;
                    206: static int iTest;
                    207: static boolean fCall_uucico;
                    208: static int iPercent;
                    209: static pid_t iPid1, iPid2;
                    210: static int cFrom1, cFrom2;
                    211: static char abLogout1[sizeof "tstout /dev/ptyp0"];
                    212: static char abLogout2[sizeof "tstout /dev/ptyp0"];
                    213: static char *zProtocols;
                    214: 
                    215: int
                    216: main (argc, argv)
                    217:      int argc;
                    218:      char **argv;
                    219: {
                    220:   int iopt;
                    221:   const char *zcmd1, *zcmd2;
                    222:   const char *zsys;
                    223:   boolean fmake = TRUE;
                    224:   int omaster1, oslave1, omaster2, oslave2;
                    225:   char abpty1[sizeof "/dev/ptyp0"];
                    226:   char abpty2[sizeof "/dev/ptyp0"];
                    227:   struct sbuf *qbuf1, *qbuf2;
                    228: 
                    229:   zcmd1 = NULL;
                    230:   zcmd2 = NULL;
                    231:   zsys = "test2";
                    232: 
                    233:   while ((iopt = getopt (argc, argv, "c:np:s:t:ux:1:2:")) != EOF)
                    234:     {
                    235:       switch (iopt)
                    236:        {
                    237:        case 'c':
                    238:          zProtocols = optarg;
                    239:          break;
                    240:        case 'n':
                    241:          fmake = FALSE;
                    242:          break;
                    243:        case 'p':
                    244:          iPercent = (int) strtol (optarg, (char **) NULL, 10);
                    245:          srand ((unsigned int) ixsysdep_time ((long *) NULL));
                    246:          break;
                    247:        case 's':
                    248:          zsys = optarg;
                    249:          break;
                    250:        case 't':
                    251:          iTest = (int) strtol (optarg, (char **) NULL, 10);
                    252:          break;
                    253:        case 'u':
                    254:          fCall_uucico = TRUE;
                    255:          break;
                    256:        case 'x':
                    257:          zDebug = optarg;
                    258:          break;
                    259:        case '1':
                    260:          zcmd1 = optarg;
                    261:          break;
                    262:        case '2':
                    263:          zcmd2 = optarg;
                    264:          break;
                    265:        default:
                    266:          fprintf (stderr,
                    267:                   "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n",
                    268:                   VERSION);
                    269:          fprintf (stderr,
                    270:                   "Usage: tstuu [-xn] [-t #] [-u] [-1 cmd] [-2 cmd]\n");
                    271:          exit (EXIT_FAILURE);
                    272:        }
                    273:     }
                    274: 
                    275:   if (fCall_uucico && zcmd2 == NULL)
                    276:     zcmd2 = ZUUCICO_CMD;
                    277: 
                    278:   uprepare_test (fmake, iTest, fCall_uucico, zsys);
                    279: 
                    280:   (void) remove ("/usr/tmp/tstuu/spool1/core");
                    281:   (void) remove ("/usr/tmp/tstuu/spool2/core");
                    282: 
                    283:   omaster1 = -1;
                    284:   oslave1 = -1;
                    285:   omaster2 = -1;
                    286:   oslave2 = -1;
                    287: 
                    288: #if ! HAVE_STREAMS_PTYS
                    289: 
                    290:   {
                    291:     char *zptyname;
                    292:     const char *zpty;
                    293: 
                    294:     zptyname = abpty1;
                    295: 
                    296:     for (zpty = "pqrs"; *zpty != '\0'; ++zpty)
                    297:       {
                    298:        int ipty;
                    299: 
                    300:        for (ipty = 0; ipty < 16; ipty++)
                    301:          {
                    302:            int om, os;
                    303:            FILE *e;
                    304:   
                    305:            sprintf (zptyname, "/dev/pty%c%c", *zpty,
                    306:                     "0123456789abcdef"[ipty]);
                    307:            om = open (zptyname, O_RDWR);
                    308:            if (om < 0)
                    309:              continue;
                    310:            zptyname[5] = 't';
                    311:            os = open (zptyname, O_RDWR);
                    312:            if (os < 0)
                    313:              {
                    314:                (void) close (om);
                    315:                continue;
                    316:              }
                    317: 
                    318:            if (omaster1 == -1)
                    319:              {
                    320:                omaster1 = om;
                    321:                oslave1 = os;
                    322: 
                    323:                e = fopen ("/usr/tmp/tstuu/pty1", "w");
                    324:                if (e == NULL)
                    325:                  {
                    326:                    perror ("fopen");
                    327:                    exit (EXIT_FAILURE);
                    328:                  }
                    329:                fprintf (e, "%s", zptyname + 5);
                    330:                if (fclose (e) != 0)
                    331:                  {
                    332:                    perror ("fclose");
                    333:                    exit (EXIT_FAILURE);
                    334:                  }
                    335: 
                    336:                zptyname = abpty2;
                    337:              }
                    338:            else
                    339:              {
                    340:                omaster2 = om;
                    341:                oslave2 = os;
                    342: 
                    343:                e = fopen ("/usr/tmp/tstuu/pty2", "w");
                    344:                if (e == NULL)
                    345:                  {
                    346:                    perror ("fopen");
                    347:                    exit (EXIT_FAILURE);
                    348:                  }
                    349:                fprintf (e, "%s", zptyname + 5);
                    350:                if (fclose (e) != 0)
                    351:                  {
                    352:                    perror ("fclose");
                    353:                    exit (EXIT_FAILURE);
                    354:                  }
                    355:                break;
                    356:              }
                    357:          }
                    358: 
                    359:        if (omaster1 != -1 && omaster2 != -1)
                    360:          break;
                    361:       }
                    362:   }
                    363: 
                    364: #else /* HAVE_STREAMS_PTYS */
                    365: 
                    366:   {
                    367:     int ipty;
                    368: 
                    369:     for (ipty = 0; ipty < 2; ipty++)
                    370:       {
                    371:        int om, os;
                    372:        FILE *e;
                    373:        char *znam;
                    374:        struct termio stio;
                    375: 
                    376:        om = open ((char *) "/dev/ptmx", O_RDWR);
                    377:        if (om < 0)
                    378:          break;
                    379:        znam = ptsname (om);
                    380:        if (znam == NULL)
                    381:          break;
                    382:        if (unlockpt (om) != 0
                    383:            || grantpt (om) != 0)
                    384:          break;
                    385: 
                    386:        os = open (znam, O_RDWR);
                    387:        if (os < 0)
                    388:          {
                    389:            (void) close (om);
                    390:            om = -1;
                    391:            break;
                    392:          }
                    393: 
                    394:        if (ioctl (os, I_PUSH, "ptem") < 0
                    395:            || ioctl(os, I_PUSH, "ldterm") < 0)
                    396:          {
                    397:            perror ("ioctl");
                    398:            exit (EXIT_FAILURE);
                    399:          }
                    400: 
                    401:        /* Can this really be right? */
                    402:        memset (&stio, 0, sizeof (stio));
                    403:        stio.c_cflag = B9600 | CS8 | CREAD | HUPCL;
                    404: 
                    405:        if (ioctl(os, TCSETA, &stio) < 0)
                    406:          {
                    407:            perror ("TCSETA");
                    408:            exit (EXIT_FAILURE);
                    409:          }
                    410: 
                    411:        if (omaster1 == -1)
                    412:          {
                    413:            strcpy (abpty1, znam);
                    414:            omaster1 = om;
                    415:            oslave1 = os;
                    416:            e = fopen ("/usr/tmp/tstuu/pty1", "w");
                    417:            if (e == NULL)
                    418:              {
                    419:                perror ("fopen");
                    420:                exit (EXIT_FAILURE);
                    421:              }
                    422:            fprintf (e, "%s", znam + 5);
                    423:            if (fclose (e) != 0)
                    424:              {
                    425:                perror ("fclose");
                    426:                exit (EXIT_FAILURE);
                    427:              }
                    428:          }
                    429:        else
                    430:          {
                    431:            strcpy (abpty2, znam);
                    432:            omaster2 = om;
                    433:            oslave2 = os;
                    434:            e = fopen ("/usr/tmp/tstuu/pty2", "w");
                    435:            if (e == NULL)
                    436:              {
                    437:                perror ("fopen");
                    438:                exit (EXIT_FAILURE);
                    439:              }
                    440:            fprintf (e, "%s", znam + 5);
                    441:            if (fclose (e) != 0)
                    442:              {
                    443:                perror ("fclose");
                    444:                exit (EXIT_FAILURE);
                    445:              }
                    446:          }
                    447:       }
                    448:   }
                    449: 
                    450: #endif /* HAVE_STREAMS_PTYS */
                    451: 
                    452:   if (omaster2 == -1)
                    453:     {
                    454:       fprintf (stderr, "No pseudo-terminals available\n");
                    455:       exit (EXIT_FAILURE);
                    456:     }
                    457: 
                    458:   /* Make sure we can or these into an int for the select call.  Most
                    459:      systems could use 31 instead of 15, but it should never be a
                    460:      problem.  */
                    461:   if (omaster1 > 15 || omaster2 > 15)
                    462:     {
                    463:       fprintf (stderr, "File descriptors are too large\n");
                    464:       exit (EXIT_FAILURE);
                    465:     }
                    466: 
                    467:   /* Prepare to log out the command if it is a login command.  On
                    468:      Ultrix 4.0 uucico can only be run from login for some reason.  */
                    469: 
                    470:   if (zcmd1 == NULL
                    471:       || strncmp (zcmd1, "login", sizeof "login" - 1) != 0)
                    472:     abLogout1[0] = '\0';
                    473:   else
                    474:     sprintf (abLogout1, "tstout %s", abpty1);
                    475: 
                    476:   if (zcmd2 == NULL
                    477:       || strncmp (zcmd2, "login", sizeof "login" - 1) != 0)
                    478:     abLogout2[0] = '\0';
                    479:   else
                    480:     sprintf (abLogout2, "tstout %s", abpty2);
                    481: 
                    482:   iPid1 = fork ();
                    483:   if (iPid1 < 0)
                    484:     {
                    485:       perror ("fork");
                    486:       exit (EXIT_FAILURE);
                    487:     }
                    488:   else if (iPid1 == 0)
                    489:     {
                    490:       if (close (0) < 0
                    491:          || close (1) < 0
                    492:          || close (omaster1) < 0
                    493:          || close (omaster2) < 0
                    494:          || close (oslave2) < 0)
                    495:        perror ("close");
                    496: 
                    497:       if (dup2 (oslave1, 0) < 0
                    498:          || dup2 (oslave1, 1) < 0)
                    499:        perror ("dup2");
                    500: 
                    501:       if (close (oslave1) < 0)
                    502:        perror ("close");
                    503: 
                    504:       if (zDebug != NULL)
                    505:        fprintf (stderr, "About to exec first process\n");
                    506: 
                    507:       if (zcmd1 != NULL)
                    508:        exit (system ((char *) zcmd1));
                    509:       else
                    510:        {
                    511:          (void) execl ("uucico", "uucico", "-I", "/usr/tmp/tstuu/Config1",
                    512:                        "-q", "-S", zsys, "-pstdin", (const char *) NULL);
                    513:          perror ("execl failed");
                    514:          exit (EXIT_FAILURE);
                    515:        }
                    516:     }
                    517: 
                    518:   iPid2 = fork ();
                    519:   if (iPid2 < 0)
                    520:     {
                    521:       perror ("fork");
                    522:       kill (iPid1, SIGTERM);
                    523:       exit (EXIT_FAILURE);
                    524:     }
                    525:   else if (iPid2 == 0)
                    526:     {
                    527:       if (close (0) < 0
                    528:          || close (1) < 0
                    529:          || close (omaster1) < 0
                    530:          || close (oslave1) < 0
                    531:          || close (omaster2) < 0)
                    532:        perror ("close");
                    533: 
                    534:       if (dup2 (oslave2, 0) < 0
                    535:          || dup2 (oslave2, 1) < 0)
                    536:        perror ("dup2");
                    537: 
                    538:       if (close (oslave2) < 0)
                    539:        perror ("close");
                    540: 
                    541:       if (zDebug != NULL)
                    542:        fprintf (stderr, "About to exec second process\n");
                    543: 
                    544:       if (fCall_uucico)
                    545:        {
                    546:          (void) execl (UUCICO_EXECL, (const char *) NULL);
                    547:          perror ("execl failed");
                    548:          exit (EXIT_FAILURE);
                    549:        }
                    550:       else if (zcmd2 != NULL)
                    551:        exit (system ((char *) zcmd2));
                    552:       else
                    553:        {
                    554:          (void) execl ("uucico", "uucico", "-I", "/usr/tmp/tstuu/Config2",
                    555:                        "-lq", (const char *)NULL);
                    556:          perror ("execl failed");
                    557:          exit (EXIT_FAILURE);
                    558:        }
                    559:     }
                    560: 
                    561:   signal (SIGCHLD, uchild);
                    562: 
                    563:   if (fcntl (omaster1, F_SETFL, O_NDELAY | O_NONBLOCK) < 0
                    564:       && errno == EINVAL)
                    565:     (void) fcntl (omaster1, F_SETFL, O_NONBLOCK);
                    566:   if (fcntl (omaster2, F_SETFL, O_NDELAY | O_NONBLOCK) < 0
                    567:       && errno == EINVAL)
                    568:     (void) fcntl (omaster2, F_SETFL, O_NONBLOCK);
                    569: 
                    570:   qbuf1 = NULL;
                    571:   qbuf2 = NULL;
                    572: 
                    573:   while (TRUE)
                    574:     {
                    575:       int o1, o2;
                    576:       boolean fcont;
                    577: 
                    578:       o1 = omaster1;
                    579:       o2 = omaster2;
                    580:       uchoose (&o1, &o2);
                    581: 
                    582:       if (o1 == -1 && o2 == -1)
                    583:        {
                    584:          if (zDebug != NULL)
                    585:            fprintf (stderr, "Five second pause\n");
                    586:          continue;
                    587:        }
                    588: 
                    589:       if (o1 != -1)
                    590:        cFrom1 += cread (omaster1, &qbuf1);
                    591: 
                    592:       if (o2 != -1)
                    593:        cFrom2 += cread (omaster2, &qbuf2);
                    594: 
                    595:       do
                    596:        {
                    597:          fcont = FALSE;
                    598: 
                    599:          if (qbuf1 != NULL
                    600:              && fwritable (omaster2)
                    601:              && fsend (omaster2, oslave2, &qbuf1))
                    602:            fcont = TRUE;
                    603: 
                    604:          if (qbuf2 != NULL
                    605:              && fwritable (omaster1)
                    606:              && fsend (omaster1, oslave1, &qbuf2))
                    607:            fcont = TRUE;
                    608: 
                    609:          if (! fcont
                    610:              && (qbuf1 != NULL || qbuf2 != NULL))
                    611:            {
                    612:              long cgot1, cgot2;
                    613: 
                    614:              cgot1 = cread (omaster1, &qbuf1);
                    615:              cFrom1 += cgot1;
                    616:              cgot2 = cread (omaster2, &qbuf2);
                    617:              cFrom2 += cgot2;
                    618:              fcont = TRUE;
                    619:            }
                    620:        }
                    621:       while (fcont);
                    622:     }
                    623: 
                    624:   /*NOTREACHED*/
                    625: }
                    626: 
                    627: /* When a child dies, kill them both.  */
                    628: 
                    629: static RETSIGTYPE
                    630: uchild (isig)
                    631:      int isig;
                    632: {
                    633:   struct tms sbase, s1, s2;
                    634: 
                    635:   signal (SIGCHLD, SIG_DFL);
                    636: 
                    637:   /* Give the processes a chance to die on their own.  */
                    638:   sleep (2);
                    639: 
                    640:   (void) kill (iPid1, SIGTERM);
                    641:   (void) kill (iPid2, SIGTERM);
                    642: 
                    643:   (void) times (&sbase);
                    644: 
                    645: #if HAVE_WAITPID
                    646:   (void) waitpid (iPid1, (pointer) NULL, 0);
                    647: #else /* ! HAVE_WAITPID */
                    648: #if HAVE_WAIT4
                    649:   (void) wait4 (iPid1, (pointer) NULL, 0, (struct rusage *) NULL);
                    650: #else /* ! HAVE_WAIT4 */
                    651:   (void) wait ((wait_status *) NULL);
                    652: #endif /* ! HAVE_WAIT4 */
                    653: #endif /* ! HAVE_WAITPID */
                    654: 
                    655:   (void) times (&s1);
                    656: 
                    657: #if HAVE_WAITPID
                    658:   (void) waitpid (iPid2, (pointer) NULL, 0);
                    659: #else /* ! HAVE_WAITPID */
                    660: #if HAVE_WAIT4
                    661:   (void) wait4 (iPid2, (wait_status *) NULL, 0, (struct rusage *) NULL);
                    662: #else /* ! HAVE_WAIT4 */
                    663:   (void) wait ((wait_status *) NULL);
                    664: #endif /* ! HAVE_WAIT4 */
                    665: #endif /* ! HAVE_WAITPID */
                    666: 
                    667:   (void) times (&s2);
                    668: 
                    669:   fprintf (stderr,
                    670:           " First child: user: %g; system: %g\n",
                    671:           (double) (s1.tms_cutime - sbase.tms_cutime) / (double) TIMES_TICK,
                    672:           (double) (s1.tms_cstime - sbase.tms_cstime) / (double) TIMES_TICK);
                    673:   fprintf (stderr,
                    674:           "Second child: user: %g; system: %g\n",
                    675:           (double) (s2.tms_cutime - s1.tms_cutime) / (double) TIMES_TICK,
                    676:           (double) (s2.tms_cstime - s1.tms_cstime) / (double) TIMES_TICK);
                    677: 
                    678:   ucheck_test (iTest, fCall_uucico);
                    679: 
                    680:   if (abLogout1[0] != '\0')
                    681:     {
                    682:       if (zDebug != NULL)
                    683:        fprintf (stderr, "Executing %s\n", abLogout1);
                    684:       (void) system (abLogout1);
                    685:     }
                    686:   if (abLogout2[0] != '\0')
                    687:     {
                    688:       if (zDebug != NULL)
                    689:        fprintf (stderr, "Executing %s\n", abLogout2);
                    690:       (void) system (abLogout2);
                    691:     }
                    692: 
                    693:   fprintf (stderr, "Wrote %d bytes from 1 to 2\n", cFrom1);
                    694:   fprintf (stderr, "Wrote %d bytes from 2 to 1\n", cFrom2);
                    695: 
                    696:   if (access ("/usr/tmp/tstuu/spool1/core", R_OK) == 0)
                    697:     fprintf (stderr, "core file 1 exists\n");
                    698:   if (access ("/usr/tmp/tstuu/spool2/core", R_OK) == 0)
                    699:     fprintf (stderr, "core file 2 exists\n");
                    700: 
                    701:   exit (EXIT_SUCCESS);
                    702: }
                    703: 
                    704: /* Open a file without error.  */
                    705: 
                    706: static FILE *
                    707: xfopen (zname, zmode)
                    708:      const char *zname;
                    709:      const char *zmode;
                    710: {
                    711:   FILE *eret;
                    712: 
                    713:   eret = fopen (zname, zmode);
                    714:   if (eret == NULL)
                    715:     {
                    716:       perror (zname);
                    717:       exit (EXIT_FAILURE);
                    718:     }
                    719:   return eret;
                    720: }
                    721: 
                    722: /* Close a file without error.  */
                    723: 
                    724: static void xfclose P((FILE *e));
                    725: 
                    726: static void
                    727: xfclose (e)
                    728:      FILE *e;
                    729: {
                    730:   if (fclose (e) != 0)
                    731:     {
                    732:       perror ("fclose");
                    733:       exit (EXIT_FAILURE);
                    734:     }
                    735: }
                    736: 
                    737: /* Create a test file.  */
                    738: 
                    739: static void
                    740: umake_file (z, c)
                    741:      const char *z;
                    742:      int c;
                    743: {
                    744:   int i;
                    745:   FILE *e;
                    746: 
                    747:   e = xfopen (z, "w");
                    748:        
                    749:   for (i = 0; i < 256; i++)
                    750:     {
                    751:       int i2;
                    752: 
                    753:       for (i2 = 0; i2 < 256; i2++)
                    754:        putc (i, e);
                    755:     }
                    756: 
                    757:   for (i = 0; i < c; i++)
                    758:     putc (i, e);
                    759: 
                    760:   xfclose (e);
                    761: }
                    762: 
                    763: /* Check a test file.  */
                    764: 
                    765: static void
                    766: ucheck_file (z, zerr, c)
                    767:      const char *z;
                    768:      const char *zerr;
                    769:      int c;
                    770: {
                    771:   int i;
                    772:   FILE *e;
                    773: 
                    774:   e = xfopen (z, "r");
                    775: 
                    776:   for (i = 0; i < 256; i++)
                    777:     {
                    778:       int i2;
                    779: 
                    780:       for (i2 = 0; i2 < 256; i2++)
                    781:        {
                    782:          int bread;
                    783: 
                    784:          bread = getc (e);
                    785:          if (bread == EOF)
                    786:            {
                    787:              fprintf (stderr,
                    788:                       "%s: Unexpected EOF at position %d,%d\n",
                    789:                       zerr, i, i2);
                    790:              xfclose (e);
                    791:              return;
                    792:            }
                    793:          if (bread != i)
                    794:            fprintf (stderr,
                    795:                     "%s: At position %d,%d got %d expected %d\n",
                    796:                     zerr, i, i2, bread, i);
                    797:        }
                    798:     }
                    799: 
                    800:   for (i = 0; i < c; i++)
                    801:     {
                    802:       int bread;
                    803: 
                    804:       bread = getc (e);
                    805:       if (bread == EOF)
                    806:        {
                    807:          fprintf (stderr, "%s: Unexpected EOF at extra %d\n", zerr, i);
                    808:          xfclose (e);
                    809:          return;
                    810:        }
                    811:       if (bread != i)
                    812:        fprintf (stderr, "%s: At extra %d got %d expected %d\n",
                    813:                 zerr, i, bread, i);
                    814:     }
                    815: 
                    816:   if (getc (e) != EOF)
                    817:     fprintf (stderr, "%s: File is too long", zerr);
                    818: 
                    819:   xfclose (e);
                    820: }
                    821: 
                    822: /* Prepare all the configuration files for testing.  */
                    823: 
                    824: static void
                    825: uprepare_test (fmake, itest, fcall_uucico, zsys)
                    826:      boolean fmake;
                    827:      int itest;
                    828:      boolean fcall_uucico;
                    829:      const char *zsys;
                    830: {
                    831:   FILE *e;
                    832:   const char *zuucp1, *zuucp2;
                    833:   const char *zuux1, *zuux2;
                    834:   char ab[1000];
                    835:   const char *zfrom;
                    836:   const char *zto;
                    837: 
                    838: /* We must make /usr/tmp/tstuu world writeable or we won't be able to
                    839:    receive files into it.  */
                    840:   (void) umask (0);
                    841: 
                    842: #ifndef S_IWOTH
                    843: #define S_IWOTH 02
                    844: #endif
                    845: 
                    846:   if (mkdir ((char *) "/usr/tmp/tstuu",
                    847:             IPUBLIC_DIRECTORY_MODE | S_IWOTH) != 0
                    848:       && errno != EEXIST)
                    849:     {
                    850:       perror ("mkdir");
                    851:       exit (EXIT_FAILURE);
                    852:     }
                    853: 
                    854:   if (mkdir ((char *) "/usr/tmp/tstuu/spool1", IPUBLIC_DIRECTORY_MODE) != 0
                    855:       && errno != EEXIST)
                    856:     {
                    857:       perror ("mkdir");
                    858:       exit (EXIT_FAILURE);
                    859:     }
                    860: 
                    861:   if (mkdir ((char *) "/usr/tmp/tstuu/spool2", IPUBLIC_DIRECTORY_MODE) != 0
                    862:       && errno != EEXIST)
                    863:     {
                    864:       perror ("mkdir");
                    865:       exit (EXIT_FAILURE);
                    866:     }
                    867: 
                    868:   if (fmake)
                    869:     {
                    870:       e = xfopen ("/usr/tmp/tstuu/Config1", "w");
                    871: 
                    872:       fprintf (e, "# First test configuration file\n");
                    873:       fprintf (e, "nodename test1\n");
                    874:       fprintf (e, "spool /usr/tmp/tstuu/spool1\n");
                    875:       fprintf (e, "lockdir /usr/tmp/tstuu/spool1\n");
                    876:       fprintf (e, "sysfile /usr/tmp/tstuu/System1\n");
                    877:       fprintf (e, "sysfile /usr/tmp/tstuu/System1.2\n");
                    878:       fprintf (e, "portfile /usr/tmp/tstuu/Port1\n");
                    879:       (void) remove ("/usr/tmp/tstuu/Log1");
                    880: #if ! HAVE_HDB_LOGGING
                    881:       fprintf (e, "logfile /usr/tmp/tstuu/Log1\n");
                    882: #else
                    883:       fprintf (e, "%s\n", "logfile /usr/tmp/tstuu/Log1/%s/%s");
                    884: #endif
                    885:       fprintf (e, "statfile /usr/tmp/tstuu/Stats1\n");
                    886:       fprintf (e, "debugfile /usr/tmp/tstuu/Debug1\n");
                    887:       fprintf (e, "callfile /usr/tmp/tstuu/Call1\n");
                    888:       fprintf (e, "pubdir /usr/tmp/tstuu\n");
                    889: #if HAVE_V2_CONFIG
                    890:       fprintf (e, "v2-files no\n");
                    891: #endif
                    892: #if HAVE_HDB_CONFIG
                    893:       fprintf (e, "hdb-files no\n");
                    894: #endif
                    895:       if (zDebug != NULL)
                    896:        fprintf (e, "debug %s\n", zDebug);
                    897: 
                    898:       xfclose (e);
                    899: 
                    900:       e = xfopen ("/usr/tmp/tstuu/System1", "w");
                    901: 
                    902:       fprintf (e, "# This file is ignored, to test multiple system files\n");
                    903:       fprintf (e, "time never\n");
                    904: 
                    905:       xfclose (e);
                    906: 
                    907:       e = xfopen ("/usr/tmp/tstuu/System1.2", "w");
                    908: 
                    909:       fprintf (e, "# First test system file\n");
                    910:       fprintf (e, "time any\n");
                    911:       fprintf (e, "port stdin\n");
                    912:       fprintf (e, "# That was the defaults\n");
                    913:       fprintf (e, "system %s\n", zsys);
                    914:       if (! fcall_uucico)
                    915:        {
                    916:          FILE *eprog;
                    917: 
                    918:          eprog = xfopen ("/usr/tmp/tstuu/Chat1", "w");
                    919: 
                    920:          /* Wait for the other side to open the port and flush input.  */
                    921:          fprintf (eprog, "sleep 2\n");
                    922:          fprintf (eprog,
                    923:                   "echo password $1 speed $2 1>&2\n");
                    924:          fprintf (eprog, "echo test1\n");
                    925:          fprintf (eprog, "exit 0\n");
                    926: 
                    927:          xfclose (eprog);
                    928: 
                    929:          if (chmod ("/usr/tmp/tstuu/Chat1",
                    930:                     S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0)
                    931:            {
                    932:              perror ("chmod (/usr/tmp/tstuu/Chat1)");
                    933:              exit (EXIT_FAILURE);
                    934:            }
                    935: 
                    936:          fprintf (e, "chat-program /usr/tmp/tstuu/Chat1 \\P \\S\n");
                    937: 
                    938:          fprintf (e, "chat word: \\P\n");
                    939:          fprintf (e, "chat-fail login;\n");
                    940:          fprintf (e, "call-login *\n");
                    941:          fprintf (e, "call-password *\n");
                    942:        }
                    943:       else
                    944:        fprintf (e, "chat \"\"\n");
                    945:       fprintf (e, "call-transfer yes\n");
                    946:       fprintf (e, "commands cat\n");
                    947:       if (! fcall_uucico && iPercent == 0)
                    948:        {
                    949:          fprintf (e, "protocol-parameter g window 7\n");
                    950:          fprintf (e, "protocol-parameter g packet-size 4096\n");
                    951:          fprintf (e, "protocol-parameter j avoid \\377\n");
                    952:        }
                    953:       if (zProtocols != NULL)
                    954:        fprintf (e, "protocol %s\n", zProtocols);
                    955: 
                    956:       xfclose (e);
                    957: 
                    958:       e = xfopen ("/usr/tmp/tstuu/Port1", "w");
                    959: 
                    960:       fprintf (e, "port stdin\n");
                    961:       fprintf (e, "type stdin\n");
                    962:       fprintf (e, "pty true\n");
                    963: 
                    964:       xfclose (e);
                    965: 
                    966:       e = xfopen ("/usr/tmp/tstuu/Call1", "w");
                    967: 
                    968:       fprintf (e, "Call out password file\n");
                    969:       fprintf (e, "%s test1 pass1\n", zsys);
                    970: 
                    971:       xfclose (e);
                    972: 
                    973:       if (! fcall_uucico)
                    974:        {
                    975:          FILE *eprog;
                    976: 
                    977:          e = xfopen ("/usr/tmp/tstuu/Config2", "w");
                    978: 
                    979:          fprintf (e, "# Second test configuration file\n");
                    980:          fprintf (e, "nodename test2\n");
                    981:          fprintf (e, "spool /usr/tmp/tstuu/spool2\n");
                    982:          fprintf (e, "lockdir /usr/tmp/tstuu/spool2\n");
                    983:          fprintf (e, "sysfile /usr/tmp/tstuu/System2\n");
                    984:          (void) remove ("/usr/tmp/tstuu/Log2");
                    985: #if ! HAVE_HDB_LOGGING
                    986:          fprintf (e, "logfile /usr/tmp/tstuu/Log2\n");
                    987: #else
                    988:          fprintf (e, "%s\n", "logfile /usr/tmp/tstuu/Log2/%s/%s");
                    989: #endif
                    990:          fprintf (e, "statfile /usr/tmp/tstuu/Stats2\n");
                    991:          fprintf (e, "debugfile /usr/tmp/tstuu/Debug2\n");
                    992:          fprintf (e, "passwdfile /usr/tmp/tstuu/Pass2\n");
                    993:          fprintf (e, "pubdir /usr/tmp/tstuu\n");
                    994: #if HAVE_V2_CONFIG
                    995:          fprintf (e, "v2-files no\n");
                    996: #endif
                    997: #if HAVE_HDB_CONFIG
                    998:          fprintf (e, "hdb-files no\n");
                    999: #endif
                   1000:          if (zDebug != NULL)
                   1001:            fprintf (e, "debug %s\n", zDebug);
                   1002: 
                   1003:          xfclose (e);
                   1004: 
                   1005:          e = xfopen ("/usr/tmp/tstuu/System2", "w");
                   1006: 
                   1007:          fprintf (e, "# Second test system file\n");
                   1008:          fprintf (e, "system test1\n");
                   1009:          fprintf (e, "called-login test1\n");
                   1010:          fprintf (e, "request true\n");
                   1011:          fprintf (e, "commands cat\n");
                   1012:          if (zProtocols != NULL)
                   1013:            fprintf (e, "protocol %s\n", zProtocols);
                   1014: 
                   1015:          eprog = xfopen ("/usr/tmp/tstuu/Chat2", "w");
                   1016: 
                   1017:          fprintf (eprog,
                   1018:                   "echo port $1 1>&2\n");
                   1019:          fprintf (eprog, "exit 0\n");
                   1020: 
                   1021:          xfclose (eprog);
                   1022: 
                   1023:          if (chmod ("/usr/tmp/tstuu/Chat2",
                   1024:                     S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0)
                   1025:            {
                   1026:              perror ("chmod (/usr/tmp/tstuu/Chat2");
                   1027:              exit (EXIT_FAILURE);
                   1028:            }
                   1029: 
                   1030:          fprintf (e, "called-chat-program /bin/sh /usr/tmp/tstuu/Chat2 \\Y\n");
                   1031:          fprintf (e, "time any\n");
                   1032: 
                   1033:          xfclose (e);
                   1034: 
                   1035:          e = xfopen ("/usr/tmp/tstuu/Pass2", "w");
                   1036: 
                   1037:          fprintf (e, "# Call in password file\n");
                   1038:          fprintf (e, "test1 pass1\n");
                   1039: 
                   1040:          xfclose (e);
                   1041:        }
                   1042:     }
                   1043: 
                   1044:   zuucp1 = "./uucp -I /usr/tmp/tstuu/Config1 -r";
                   1045:   zuux1 = "./uux -I /usr/tmp/tstuu/Config1 -r";
                   1046: 
                   1047:   if (fcall_uucico)
                   1048:     {
                   1049:       zuucp2 = "/usr/bin/uucp -r";
                   1050:       zuux2 = "/usr/bin/uux -r";
                   1051:     }
                   1052:   else
                   1053:     {
                   1054:       zuucp2 = "./uucp -I /usr/tmp/tstuu/Config2 -r";
                   1055:       zuux2 = "./uux -I /usr/tmp/tstuu/Config2 -r";
                   1056:     }
                   1057: 
                   1058:   /* Test transferring a file from the first system to the second.  */
                   1059:   if (itest == 0 || itest == 1)
                   1060:     {
                   1061:       zfrom = "/usr/tmp/tstuu/from1";
                   1062:       if (fcall_uucico)
                   1063:        zto = "/usr/spool/uucppublic/to1";
                   1064:       else
                   1065:        zto = "/usr/tmp/tstuu/to1";
                   1066: 
                   1067:       (void) remove (zto);
                   1068:       umake_file (zfrom, 0);
                   1069: 
                   1070:       sprintf (ab, "%s %s %s!%s", zuucp1, zfrom, zsys, zto);
                   1071:       xsystem (ab);
                   1072:     }
                   1073: 
                   1074:   /* Test having the first system request a file from the second.  */
                   1075:   if (itest == 0 || itest == 2)
                   1076:     {
                   1077:       if (fcall_uucico)
                   1078:        zfrom = "/usr/spool/uucppublic/from2";
                   1079:       else
                   1080:        zfrom = "/usr/tmp/tstuu/from2";
                   1081:       zto = "/usr/tmp/tstuu/to2";
                   1082: 
                   1083:       (void) remove (zto);
                   1084:       umake_file (zfrom, 3);
                   1085: 
                   1086:       sprintf (ab, "%s %s!%s %s", zuucp1, zsys, zfrom, zto);
                   1087:       xsystem (ab);
                   1088:     }
                   1089: 
                   1090:   /* Test having the second system send a file to the first.  */
                   1091:   if (itest == 0 || itest == 3)
                   1092:     {
                   1093:       if (fcall_uucico)
                   1094:        zfrom = "/usr/spool/uucppublic/from3";
                   1095:       else
                   1096:        zfrom = "/usr/tmp/tstuu/from3";
                   1097:       zto = "/usr/tmp/tstuu/to3";
                   1098: 
                   1099:       (void) remove (zto);
                   1100:       umake_file (zfrom, 5);
                   1101: 
                   1102:       sprintf (ab, "%s -c \\~/from3 test1!~/to3", zuucp2);
                   1103:       xsystem (ab);
                   1104:     }
                   1105: 
                   1106:   /* Test having the second system request a file from the first.  */
                   1107:   if (itest == 0 || itest == 4)
                   1108:     {
                   1109:       zfrom = "/usr/tmp/tstuu/from4";
                   1110:       if (fcall_uucico)
                   1111:        zto = "/usr/spool/uucppublic/to4";
                   1112:       else
                   1113:        zto = "/usr/tmp/tstuu/to4";
                   1114: 
                   1115:       (void) remove (zto);
                   1116:       umake_file (zfrom, 7);
                   1117: 
                   1118:       sprintf (ab, "%s test1!%s %s", zuucp2, zfrom, zto);
                   1119:       xsystem (ab);
                   1120:     }
                   1121: 
                   1122:   /* Test having the second system make an execution request.  */
                   1123:   if (itest == 0 || itest == 5)
                   1124:     {
                   1125:       zfrom = "/usr/tmp/tstuu/from5";
                   1126:       if (fcall_uucico)
                   1127:        zto = "/usr/spool/uucppublic/to5";
                   1128:       else
                   1129:        zto = "/usr/tmp/tstuu/to5";
                   1130: 
                   1131:       (void) remove (zto);
                   1132:       umake_file (zfrom, 11);
                   1133: 
                   1134:       sprintf (ab, "%s test1!cat '<%s' '>%s'", zuux2, zfrom, zto);
                   1135:       xsystem (ab);
                   1136:     }
                   1137: 
                   1138:   /* Test having the first system request a wildcard.  */
                   1139:   if (itest == 0 || itest == 6)
                   1140:     {
                   1141:       const char *zfrom1, *zfrom2;
                   1142: 
                   1143:       if (fcall_uucico)
                   1144:        {
                   1145:          zfrom = "/usr/spool/uucppublic/to6\\*";
                   1146:          zfrom1 = "/usr/spool/uucppublic/to6.1";
                   1147:          zfrom2 = "/usr/spool/uucppublic/to6.2";
                   1148:        }
                   1149:       else
                   1150:        {
                   1151:          zfrom = "/usr/tmp/tstuu/spool2/to6\\*";
                   1152:          zfrom1 = "/usr/tmp/tstuu/spool2/to6.1";
                   1153:          zfrom2 = "/usr/tmp/tstuu/spool2/to6.2";
                   1154:        }
                   1155: 
                   1156:       umake_file (zfrom1, 100);
                   1157:       umake_file (zfrom2, 101);
                   1158:       (void) remove ("/usr/tmp/tstuu/to6.1");
                   1159:       (void) remove ("/usr/tmp/tstuu/to6.2");
                   1160: 
                   1161:       sprintf (ab, "%s %s!%s /usr/tmp/tstuu", zuucp1, zsys, zfrom);
                   1162:       xsystem (ab);
                   1163:     }
                   1164: 
                   1165:   /* Test having the second system request a wildcard.  */
                   1166:   if (itest == 0 || itest == 7)
                   1167:     {
                   1168:       const char *zto1, *zto2;
                   1169: 
                   1170:       if (fcall_uucico)
                   1171:        {
                   1172:          zto = "/usr/spool/uucppublic";
                   1173:          zto1 = "/usr/spool/uucppublic/to7.1";
                   1174:          zto2 = "/usr/spool/uucppublic/to7.2";
                   1175:        }
                   1176:       else
                   1177:        {
                   1178:          zto = "/usr/tmp/tstuu";
                   1179:          zto1 = "/usr/tmp/tstuu/to7.1";
                   1180:          zto2 = "/usr/tmp/tstuu/to7.2";
                   1181:        }
                   1182: 
                   1183:       umake_file ("/usr/tmp/tstuu/spool1/to7.1", 150);
                   1184:       umake_file ("/usr/tmp/tstuu/spool1/to7.2", 155);
                   1185:       (void) remove (zto1);
                   1186:       (void) remove (zto2);
                   1187: 
                   1188:       sprintf (ab, "%s test1!/usr/tmp/tstuu/spool1/to7.\\* %s", zuucp2,
                   1189:               zto);
                   1190:       xsystem (ab);
                   1191:     }
                   1192: 
                   1193:   /* Test an E command.  This runs cat, discarding the output.  */
                   1194:   if ((itest == 0 || itest == 8) && ! fcall_uucico)
                   1195:     {
                   1196:       umake_file ("/usr/tmp/tstuu/from8", 30);
                   1197:       sprintf (ab, "%s - test2!cat < /usr/tmp/tstuu/from8", zuux1);
                   1198:       xsystem (ab);
                   1199:     }
                   1200: }
                   1201: 
                   1202: /* Try to make sure the file transfers were successful.  */
                   1203: 
                   1204: static void
                   1205: ucheck_test (itest, fcall_uucico)
                   1206:      int itest;
                   1207:      boolean fcall_uucico;
                   1208: {
                   1209:   if (itest == 0 || itest == 1)
                   1210:     {
                   1211:       if (fcall_uucico)
                   1212:        ucheck_file ("/usr/spool/uucppublic/to1", "test 1", 0);
                   1213:       else
                   1214:        ucheck_file ("/usr/tmp/tstuu/to1", "test 1", 0);
                   1215:     }
                   1216: 
                   1217:   if (itest == 0 || itest == 2)
                   1218:     ucheck_file ("/usr/tmp/tstuu/to2", "test 2", 3);
                   1219: 
                   1220:   if (itest == 0 || itest == 3)
                   1221:     ucheck_file ("/usr/tmp/tstuu/to3", "test 3", 5);
                   1222: 
                   1223:   if (itest == 0 || itest == 4)
                   1224:     {
                   1225:       if (fcall_uucico)
                   1226:        ucheck_file ("/usr/spool/uucppublic/to4", "test 4", 7);
                   1227:       else
                   1228:        ucheck_file ("/usr/tmp/tstuu/to4", "test 4", 7);
                   1229:     }
                   1230: 
                   1231:   if (itest == 0 || itest == 6)
                   1232:     {
                   1233:       ucheck_file ("/usr/tmp/tstuu/to6.1", "test 6.1", 100);
                   1234:       ucheck_file ("/usr/tmp/tstuu/to6.2", "test 6.2", 101);
                   1235:     }
                   1236: 
                   1237:   if (itest == 0 || itest == 7)
                   1238:     {
                   1239:       const char *zto1, *zto2;
                   1240: 
                   1241:       if (fcall_uucico)
                   1242:        {
                   1243:          zto1 = "/usr/spool/uucppublic/to7.1";
                   1244:          zto2 = "/usr/spool/uucppublic/to7.2";
                   1245:        }
                   1246:       else
                   1247:        {
                   1248:          zto1 = "/usr/tmp/tstuu/to7.1";
                   1249:          zto2 = "/usr/tmp/tstuu/to7.2";
                   1250:        }
                   1251: 
                   1252:       ucheck_file (zto1, "test 7.1", 150);
                   1253:       ucheck_file (zto2, "test 7.2", 155);
                   1254:     }
                   1255: }
                   1256: 
                   1257: /* A debugging routine used when displaying buffers.  */
                   1258: 
                   1259: static int
                   1260: cpshow (z, ichar)
                   1261:      char *z;
                   1262:      int ichar;
                   1263: {
                   1264:   if (isprint (BUCHAR (ichar)) && ichar != '\"')
                   1265:     {
                   1266:       *z = (char) ichar;
                   1267:       return 1;
                   1268:     }
                   1269: 
                   1270:   *z++ = '\\';
                   1271: 
                   1272:   switch (ichar)
                   1273:     {
                   1274:     case '\n':
                   1275:       *z = 'n';
                   1276:       return 2;
                   1277:     case '\r':
                   1278:       *z = 'r';
                   1279:       return 2;
                   1280:     case '\"':
                   1281:       *z = '\"';
                   1282:       return 2;
                   1283:     default:
                   1284:       sprintf (z, "%03o", (unsigned int)(ichar & 0xff));
                   1285:       return strlen (z) + 1;
                   1286:     }
                   1287: }      
                   1288: 
                   1289: /* Pick one of two file descriptors which is ready for reading, or
                   1290:    return in five seconds.  If the argument is ready for reading,
                   1291:    leave it alone; otherwise set it to -1.  */
                   1292: 
                   1293: static void
                   1294: uchoose (po1, po2)
                   1295:      int *po1;
                   1296:      int *po2;
                   1297: {
                   1298: #if HAVE_SELECT
                   1299: 
                   1300:   int iread;
                   1301:   struct timeval stime;
                   1302: 
                   1303:   iread = (1 << *po1) | (1 << *po2);
                   1304:   stime.tv_sec = 5;
                   1305:   stime.tv_usec = 0;
                   1306: 
                   1307:   if (select ((*po1 > *po2 ? *po1 : *po2) + 1, (pointer) &iread,
                   1308:              (pointer) NULL, (pointer) NULL, &stime) < 0)
                   1309:     {
                   1310:       perror ("select");
                   1311:       uchild (SIGCHLD);
                   1312:     }
                   1313: 
                   1314:   if ((iread & (1 << *po1)) == 0)
                   1315:     *po1 = -1;
                   1316: 
                   1317:   if ((iread & (1 << *po2)) == 0)
                   1318:     *po2 = -1;
                   1319: 
                   1320: #else /* ! HAVE_SELECT */
                   1321: 
                   1322: #if HAVE_POLL
                   1323: 
                   1324:   struct pollfd as[2];
                   1325: 
                   1326:   as[0].fd = *po1;
                   1327:   as[0].events = POLLIN;
                   1328:   as[1].fd = *po2;
                   1329:   as[1].events = POLLIN;
                   1330: 
                   1331:   if (poll (as, 2, 5 * 1000) < 0)
                   1332:     {
                   1333:       perror ("poll");
                   1334:       uchild (SIGCHLD);
                   1335:     }
                   1336: 
                   1337:   if ((as[0].revents & POLLIN) == 0)
                   1338:     *po1 = -1;
                   1339:   
                   1340:   if ((as[1].revents & POLLIN) == 0)
                   1341:     *po2 = -1;
                   1342: 
                   1343: #endif /* HAVE_POLL */
                   1344: #endif /* ! HAVE_SELECT */
                   1345: }
                   1346: 
                   1347: /* Read some data from a file descriptor.  This keeps reading until
                   1348:    one of the reads gets no data.  */
                   1349: 
                   1350: static long
                   1351: cread (o, pqbuf)
                   1352:      int o;
                   1353:      struct sbuf **pqbuf;
                   1354: {
                   1355:   long ctotal;
                   1356: 
                   1357:   while (*pqbuf != NULL && (*pqbuf)->qnext != NULL)
                   1358:     pqbuf = &(*pqbuf)->qnext;
                   1359: 
                   1360:   ctotal = 0;
                   1361: 
                   1362:   while (TRUE)
                   1363:     {
                   1364:       int cgot;
                   1365: 
                   1366:       if (*pqbuf != NULL
                   1367:          && (*pqbuf)->cend >= sizeof (*pqbuf)->ab)
                   1368:        pqbuf = &(*pqbuf)->qnext;
                   1369: 
                   1370:       if (*pqbuf == NULL)
                   1371:        {
                   1372:          *pqbuf = (struct sbuf *) malloc (sizeof (struct sbuf));
                   1373:          if (*pqbuf == NULL)
                   1374:            {
                   1375:              fprintf (stderr, "Out of memory\n");
                   1376:              uchild (SIGCHLD);
                   1377:            }
                   1378:          (*pqbuf)->qnext = NULL;
                   1379:          (*pqbuf)->cstart = 0;
                   1380:          (*pqbuf)->cend = 0;
                   1381:        }
                   1382:       
                   1383:       cgot = read (o, (*pqbuf)->ab + (*pqbuf)->cend,
                   1384:                   (sizeof (*pqbuf)->ab) - (*pqbuf)->cend);
                   1385:       if (cgot < 0)
                   1386:        {
                   1387:          if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENODATA)
                   1388:            cgot = 0;
                   1389:          else
                   1390:            {
                   1391:              perror ("read");
                   1392:              uchild (SIGCHLD);
                   1393:            }
                   1394:        }
                   1395: 
                   1396:       if (cgot == 0)
                   1397:        return ctotal;
                   1398: 
                   1399:       ctotal += cgot;
                   1400: 
                   1401:       if (zDebug != NULL)
                   1402:        {
                   1403:          char abshow[325];
                   1404:          char *zfrom;
                   1405:          char *zshow;
                   1406:          int i;
                   1407: 
                   1408:          zfrom = (*pqbuf)->ab + (*pqbuf)->cend;
                   1409:          zshow = abshow;
                   1410:          for (i = 0; i < cgot && i < 80; i++, zfrom++)
                   1411:            zshow += cpshow (zshow, *zfrom);
                   1412:          if (i < cgot)
                   1413:            {
                   1414:              *zshow++ = '.';
                   1415:              *zshow++ = '.';
                   1416:              *zshow++ = '.';
                   1417:            }
                   1418:          *zshow = '\0';
                   1419:          fprintf (stderr, "Read from %d: %d \"%s\"\n", o, cgot, abshow);
                   1420:          fflush (stderr);
                   1421:        }
                   1422: 
                   1423:       if (iPercent > 0)
                   1424:        {
                   1425:          int i;
                   1426:          int c;
                   1427: 
                   1428:          c = 0;
                   1429:          for (i = 0; i < cgot; i++)
                   1430:            {
                   1431:              if (rand () % 1000 < iPercent)
                   1432:                {
                   1433:                  ++(*pqbuf)->ab[(*pqbuf)->cend + i];
                   1434:                  ++c;
                   1435:                }
                   1436:            }
                   1437:          if (zDebug != NULL && c > 0)
                   1438:            fprintf (stderr, "Clobbered %d bytes\n", c);
                   1439:        }
                   1440: 
                   1441:       (*pqbuf)->cend += cgot;
                   1442: 
                   1443:       if (ctotal > 256)
                   1444:        return ctotal;
                   1445:     }
                   1446: }
                   1447: 
                   1448: /* Write data to a file descriptor until one of the writes gets no
                   1449:    data.  */
                   1450: 
                   1451: static boolean
                   1452: fsend (o, oslave, pqbuf)
                   1453:      int o;
                   1454:      int oslave;
                   1455:      struct sbuf **pqbuf;
                   1456: {
                   1457:   long ctotal;
                   1458: 
                   1459:   ctotal = 0;
                   1460:   while (*pqbuf != NULL)
                   1461:     {
                   1462:       int cwrite, cwrote;
                   1463: 
                   1464:       if ((*pqbuf)->cstart >= (*pqbuf)->cend)
                   1465:        {
                   1466:          struct sbuf *qfree;
                   1467: 
                   1468:          qfree = *pqbuf;
                   1469:          *pqbuf = (*pqbuf)->qnext;
                   1470:          free ((pointer) qfree);
                   1471:          continue;
                   1472:        }
                   1473: 
                   1474: #ifdef FIONREAD
                   1475:       {
                   1476:        long cunread;
                   1477: 
                   1478:        if (ioctl (oslave, FIONREAD, &cunread) < 0)
                   1479:          {
                   1480:            perror ("FIONREAD");
                   1481:            uchild (SIGCHLD);
                   1482:          }
                   1483:        if (zDebug != NULL)
                   1484:          fprintf (stderr, "%ld unread\n", cunread);
                   1485:        cwrite = 256 - cunread;
                   1486:        if (cwrite <= 0)
                   1487:          break;
                   1488:       }
                   1489: #else /* ! FIONREAD */
                   1490:       if (! fwritable (o))
                   1491:        break;
                   1492:       cwrite = 1;
                   1493: #endif /* ! FIONREAD */
                   1494: 
                   1495:       if (cwrite > (*pqbuf)->cend - (*pqbuf)->cstart)
                   1496:        cwrite = (*pqbuf)->cend - (*pqbuf)->cstart;
                   1497: 
                   1498:       cwrote = write (o, (*pqbuf)->ab + (*pqbuf)->cstart, cwrite);
                   1499:       if (cwrote < 0)
                   1500:        {
                   1501:          if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENODATA)
                   1502:            cwrote = 0;
                   1503:          else
                   1504:            {
                   1505:              perror ("write");
                   1506:              uchild (SIGCHLD);
                   1507:            }
                   1508:        }
                   1509:       
                   1510:       if (cwrote == 0)
                   1511:        break;
                   1512: 
                   1513:       ctotal += cwrote;
                   1514:       (*pqbuf)->cstart += cwrote;
                   1515:     }
                   1516: 
                   1517:   if (zDebug != NULL && ctotal > 0)
                   1518:     fprintf (stderr, "Wrote %ld to %d\n", ctotal, o);
                   1519: 
                   1520:   return ctotal > 0;
                   1521: }
                   1522: 
                   1523: /* Check whether a file descriptor can be written to.  */
                   1524: 
                   1525: static boolean
                   1526: fwritable (o)
                   1527:      int o;
                   1528: {
                   1529: #if HAVE_SELECT
                   1530: 
                   1531:   int iwrite;
                   1532:   struct timeval stime;
                   1533:   int cfds;
                   1534: 
                   1535:   iwrite = 1 << o;
                   1536: 
                   1537:   stime.tv_sec = 0;
                   1538:   stime.tv_usec = 0;
                   1539: 
                   1540:   cfds = select (o + 1, (pointer) NULL, (pointer) &iwrite,
                   1541:                 (pointer) NULL, &stime);
                   1542:   if (cfds < 0)
                   1543:     {
                   1544:       perror ("select");
                   1545:       uchild (SIGCHLD);
                   1546:     }
                   1547: 
                   1548:   return cfds > 0;
                   1549: 
                   1550: #else /* ! HAVE_SELECT */
                   1551: 
                   1552: #if HAVE_POLL
                   1553: 
                   1554:   struct pollfd s;
                   1555:   int cfds;
                   1556: 
                   1557:   s.fd = o;
                   1558:   s.events = POLLOUT;
                   1559: 
                   1560:   cfds = poll (&s, 1, 0);
                   1561:   if (cfds < 0)
                   1562:     {
                   1563:       perror ("poll");
                   1564:       uchild (SIGCHLD);
                   1565:     }
                   1566: 
                   1567:   return cfds > 0;
                   1568: 
                   1569: #endif /* HAVE_POLL */
                   1570: #endif /* ! HAVE_SELECT */
                   1571: }
                   1572: 
                   1573: /* A version of the system command that checks for errors.  */
                   1574: 
                   1575: static void
                   1576: xsystem (zcmd)
                   1577:      const char *zcmd;
                   1578: {
                   1579:   int istat;
                   1580: 
                   1581:   istat = system ((char *) zcmd);
                   1582:   if (istat != 0)
                   1583:     {
                   1584:       fprintf (stderr, "Command failed with status %d\n", istat);
                   1585:       fprintf (stderr, "%s\n", zcmd);
                   1586:       exit (EXIT_FAILURE);
                   1587:     }
                   1588: }

unix.superglobalmegacorp.com

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