Annotation of coherent/g/usr/lib/uucp/tay104/tstuu.c, revision 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.