2 Test the uucp package on a UNIX system.
4 Copyright (C) 1991, 1992, 1993, 1994, 1995 Ian Lance Taylor
6 This file is part of the Taylor UUCP package.
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 The author of the program may be contacted at ian@airs.com or
23 c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
29 const char tstuu_rcsid[] = "$FreeBSD$";
41 #include <sys/times.h>
45 #include <sys/ioctl.h>
53 #include <sys/select.h>
81 #if ! HAVE_SYS_TIME_H || ! HAVE_SELECT || TIME_WITH_SYS_TIME
91 typedef union wait wait_status;
93 typedef int wait_status;
98 extern char *ptsname ();
101 /* Get definitions for both O_NONBLOCK and O_NDELAY. */
105 #define O_NDELAY FNDELAY
106 #else /* ! defined (FNDELAY) */
108 #endif /* ! defined (FNDELAY) */
109 #endif /* ! defined (O_NDELAY) */
113 #define O_NONBLOCK FNBLOCK
114 #else /* ! defined (FNBLOCK) */
116 #endif /* ! defined (FNBLOCK) */
117 #endif /* ! defined (O_NONBLOCK) */
119 #if O_NDELAY == 0 && O_NONBLOCK == 0
120 #error No way to do nonblocking I/O
123 /* Get definitions for EAGAIN, EWOULDBLOCK and ENODATA. */
127 #define EWOULDBLOCK (-1)
128 #else /* defined (EWOULDBLOCK) */
129 #define EAGAIN EWOULDBLOCK
130 #endif /* defined (EWOULDBLOCK) */
131 #else /* defined (EAGAIN) */
133 #define EWOULDBLOCK EAGAIN
134 #endif /* ! defined (EWOULDBLOCK) */
135 #endif /* defined (EAGAIN) */
138 #define ENODATA EAGAIN
141 /* Make sure we have a CLK_TCK definition, even if it makes no sense.
142 This is in case TIMES_TICK is defined as CLK_TCK. */
147 /* Don't try too hard to get a TIMES_TICK value; it doesn't matter
151 #define TIMES_TICK CLK_TCK
154 #if TIMES_DECLARATION_OK
155 extern long times ();
159 #define SIGCHLD SIGCLD
163 #define ZUUCICO_CMD "login uucp"
164 #define UUCICO_EXECL "/bin/login", "login", "uucp"
166 #define ZUUCICO_CMD "su - nuucp"
167 #define UUCICO_EXECL "/bin/su", "su", "-", "nuucp"
170 #if ! HAVE_SELECT && ! HAVE_POLL
171 #error You need select or poll
176 #define remove unlink
179 /* Buffer chain to hold data read from a uucico. */
181 #define BUFCHARS (512)
191 /* Local functions. */
193 static void umake_file P((const char *zfile, int cextra));
194 static void uprepare_test P((boolean fmake, int itest,
195 boolean fcall_uucico,
197 static void ucheck_file P((const char *zfile, const char *zerr,
199 static void ucheck_test P((int itest, boolean fcall_uucico));
200 static RETSIGTYPE uchild P((int isig));
201 static int cpshow P((char *z, int bchar));
202 static void uchoose P((int *po1, int *po2));
203 static long cread P((int o, struct sbuf **));
204 static boolean fsend P((int o, int oslave, struct sbuf **));
205 static boolean fwritable P((int o));
206 static void xsystem P((const char *zcmd));
207 static FILE *xfopen P((const char *zname, const char *zmode));
211 static boolean fCall_uucico;
213 static pid_t iPid1, iPid2;
214 static int cFrom1, cFrom2;
215 static char abLogout1[sizeof "tstout /dev/ptyp0"];
216 static char abLogout2[sizeof "tstout /dev/ptyp0"];
217 static char *zProtocols;
225 const char *zcmd1, *zcmd2;
227 boolean fmake = TRUE;
228 int omaster1, oslave1, omaster2, oslave2;
229 char abpty1[sizeof "/dev/ptyp0"];
230 char abpty2[sizeof "/dev/ptyp0"];
231 struct sbuf *qbuf1, *qbuf2;
233 #if ! HAVE_TAYLOR_CONFIG
234 fprintf (stderr, "%s: only works when compiled with HAVE_TAYLOR_CONFIG\n",
243 while ((iopt = getopt (argc, argv, "c:np:s:t:ux:1:2:")) != EOF)
254 iPercent = (int) strtol (optarg, (char **) NULL, 10);
255 srand ((unsigned int) ixsysdep_time ((long *) NULL));
261 iTest = (int) strtol (optarg, (char **) NULL, 10);
277 "Taylor UUCP %s, copyright (C) 1991, 92, 93, 94, 1995 Ian Lance Taylor\n",
280 "Usage: tstuu [-xn] [-t #] [-u] [-1 cmd] [-2 cmd]\n");
285 if (fCall_uucico && zcmd2 == NULL)
288 uprepare_test (fmake, iTest, fCall_uucico, zsys);
290 (void) remove ("/usr/tmp/tstuu/spool1/core");
291 (void) remove ("/usr/tmp/tstuu/spool2/core");
298 #if ! HAVE_STREAMS_PTYS
306 for (zpty = "pqrs"; *zpty != '\0'; ++zpty)
310 for (ipty = 0; ipty < 16; ipty++)
315 sprintf (zptyname, "/dev/pty%c%c", *zpty,
316 "0123456789abcdef"[ipty]);
317 om = open (zptyname, O_RDWR);
321 os = open (zptyname, O_RDWR);
333 e = fopen ("/usr/tmp/tstuu/pty1", "w");
339 fprintf (e, "%s", zptyname + 5);
353 e = fopen ("/usr/tmp/tstuu/pty2", "w");
359 fprintf (e, "%s", zptyname + 5);
369 if (omaster1 != -1 && omaster2 != -1)
374 #else /* HAVE_STREAMS_PTYS */
379 for (ipty = 0; ipty < 2; ipty++)
386 om = open ((char *) "/dev/ptmx", O_RDWR);
392 if (unlockpt (om) != 0
393 || grantpt (om) != 0)
396 os = open (znam, O_RDWR);
404 if (ioctl (os, I_PUSH, "ptem") < 0
405 || ioctl(os, I_PUSH, "ldterm") < 0)
411 /* Can this really be right? */
412 memset (&stio, 0, sizeof (stio));
413 stio.c_cflag = B9600 | CS8 | CREAD | HUPCL;
415 if (ioctl(os, TCSETA, &stio) < 0)
423 strcpy (abpty1, znam);
426 e = fopen ("/usr/tmp/tstuu/pty1", "w");
432 fprintf (e, "%s", znam + 5);
441 strcpy (abpty2, znam);
444 e = fopen ("/usr/tmp/tstuu/pty2", "w");
450 fprintf (e, "%s", znam + 5);
460 #endif /* HAVE_STREAMS_PTYS */
464 fprintf (stderr, "No pseudo-terminals available\n");
468 /* Make sure we can or these into an int for the select call. Most
469 systems could use 31 instead of 15, but it should never be a
471 if (omaster1 > 15 || omaster2 > 15)
473 fprintf (stderr, "File descriptors are too large\n");
477 /* Prepare to log out the command if it is a login command. On
478 Ultrix 4.0 uucico can only be run from login for some reason. */
481 || strncmp (zcmd1, "login", sizeof "login" - 1) != 0)
484 sprintf (abLogout1, "tstout %s", abpty1);
487 || strncmp (zcmd2, "login", sizeof "login" - 1) != 0)
490 sprintf (abLogout2, "tstout %s", abpty2);
502 || close (omaster1) < 0
503 || close (omaster2) < 0
504 || close (oslave2) < 0)
507 if (dup2 (oslave1, 0) < 0
508 || dup2 (oslave1, 1) < 0)
511 if (close (oslave1) < 0)
514 /* This is said to improve the tests on Linux. */
518 fprintf (stderr, "About to exec first process\n");
521 exit (system ((char *) zcmd1));
524 (void) execl ("uucico", "uucico", "-I", "/usr/tmp/tstuu/Config1",
525 "-q", "-S", zsys, "-pstdin", (const char *) NULL);
526 perror ("execl failed");
535 kill (iPid1, SIGTERM);
542 || close (omaster1) < 0
543 || close (oslave1) < 0
544 || close (omaster2) < 0)
547 if (dup2 (oslave2, 0) < 0
548 || dup2 (oslave2, 1) < 0)
551 if (close (oslave2) < 0)
554 /* This is said to improve the tests on Linux. */
558 fprintf (stderr, "About to exec second process\n");
562 (void) execl (UUCICO_EXECL, (const char *) NULL);
563 perror ("execl failed");
566 else if (zcmd2 != NULL)
567 exit (system ((char *) zcmd2));
570 (void) execl ("uucico", "uucico", "-I", "/usr/tmp/tstuu/Config2",
571 "-lq", (const char *)NULL);
572 perror ("execl failed");
577 signal (SIGCHLD, uchild);
579 if (fcntl (omaster1, F_SETFL, O_NDELAY | O_NONBLOCK) < 0
581 (void) fcntl (omaster1, F_SETFL, O_NONBLOCK);
582 if (fcntl (omaster2, F_SETFL, O_NDELAY | O_NONBLOCK) < 0
584 (void) fcntl (omaster2, F_SETFL, O_NONBLOCK);
598 if (o1 == -1 && o2 == -1)
601 fprintf (stderr, "Five second pause\n");
606 cFrom1 += cread (omaster1, &qbuf1);
609 cFrom2 += cread (omaster2, &qbuf2);
616 && fwritable (omaster2)
617 && fsend (omaster2, oslave2, &qbuf1))
621 && fwritable (omaster1)
622 && fsend (omaster1, oslave1, &qbuf2))
626 && (qbuf1 != NULL || qbuf2 != NULL))
630 cgot1 = cread (omaster1, &qbuf1);
632 cgot2 = cread (omaster2, &qbuf2);
643 /* When a child dies, kill them both. */
649 struct tms sbase, s1, s2;
651 signal (SIGCHLD, SIG_DFL);
653 /* Give the processes a chance to die on their own. */
656 (void) kill (iPid1, SIGTERM);
657 (void) kill (iPid2, SIGTERM);
659 (void) times (&sbase);
662 (void) waitpid (iPid1, (pointer) NULL, 0);
663 #else /* ! HAVE_WAITPID */
665 (void) wait4 (iPid1, (pointer) NULL, 0, (struct rusage *) NULL);
666 #else /* ! HAVE_WAIT4 */
667 (void) wait ((wait_status *) NULL);
668 #endif /* ! HAVE_WAIT4 */
669 #endif /* ! HAVE_WAITPID */
674 (void) waitpid (iPid2, (pointer) NULL, 0);
675 #else /* ! HAVE_WAITPID */
677 (void) wait4 (iPid2, (wait_status *) NULL, 0, (struct rusage *) NULL);
678 #else /* ! HAVE_WAIT4 */
679 (void) wait ((wait_status *) NULL);
680 #endif /* ! HAVE_WAIT4 */
681 #endif /* ! HAVE_WAITPID */
686 " First child: user: %g; system: %g\n",
687 (double) (s1.tms_cutime - sbase.tms_cutime) / (double) TIMES_TICK,
688 (double) (s1.tms_cstime - sbase.tms_cstime) / (double) TIMES_TICK);
690 "Second child: user: %g; system: %g\n",
691 (double) (s2.tms_cutime - s1.tms_cutime) / (double) TIMES_TICK,
692 (double) (s2.tms_cstime - s1.tms_cstime) / (double) TIMES_TICK);
694 ucheck_test (iTest, fCall_uucico);
696 if (abLogout1[0] != '\0')
699 fprintf (stderr, "Executing %s\n", abLogout1);
700 (void) system (abLogout1);
702 if (abLogout2[0] != '\0')
705 fprintf (stderr, "Executing %s\n", abLogout2);
706 (void) system (abLogout2);
709 fprintf (stderr, "Wrote %d bytes from 1 to 2\n", cFrom1);
710 fprintf (stderr, "Wrote %d bytes from 2 to 1\n", cFrom2);
712 if (access ("/usr/tmp/tstuu/spool1/core", R_OK) == 0)
713 fprintf (stderr, "core file 1 exists\n");
714 if (access ("/usr/tmp/tstuu/spool2/core", R_OK) == 0)
715 fprintf (stderr, "core file 2 exists\n");
720 /* Open a file without error. */
723 xfopen (zname, zmode)
729 eret = fopen (zname, zmode);
738 /* Close a file without error. */
740 static void xfclose P((FILE *e));
753 /* Create a test file. */
765 for (i = 0; i < 256; i++)
769 for (i2 = 0; i2 < 256; i2++)
773 for (i = 0; i < c; i++)
779 /* Check a test file. */
782 ucheck_file (z, zerr, c)
792 for (i = 0; i < 256; i++)
796 for (i2 = 0; i2 < 256; i2++)
804 "%s: Unexpected EOF at position %d,%d\n",
811 "%s: At position %d,%d got %d expected %d\n",
812 zerr, i, i2, bread, i);
816 for (i = 0; i < c; i++)
823 fprintf (stderr, "%s: Unexpected EOF at extra %d\n", zerr, i);
828 fprintf (stderr, "%s: At extra %d got %d expected %d\n",
833 fprintf (stderr, "%s: File is too long", zerr);
838 /* Prepare all the configuration files for testing. */
841 uprepare_test (fmake, itest, fcall_uucico, zsys)
844 boolean fcall_uucico;
848 const char *zuucp1, *zuucp2;
849 const char *zuux1, *zuux2;
854 /* We must make /usr/tmp/tstuu world writeable or we won't be able to
855 receive files into it. */
862 if (mkdir ((char *) "/usr/tmp/tstuu",
863 IPUBLIC_DIRECTORY_MODE | S_IWOTH) != 0
870 if (mkdir ((char *) "/usr/tmp/tstuu/spool1", IPUBLIC_DIRECTORY_MODE) != 0
877 if (mkdir ((char *) "/usr/tmp/tstuu/spool2", IPUBLIC_DIRECTORY_MODE) != 0
886 e = xfopen ("/usr/tmp/tstuu/Config1", "w");
888 fprintf (e, "# First test configuration file\n");
889 fprintf (e, "nodename test1\n");
890 fprintf (e, "spool /usr/tmp/tstuu/spool1\n");
891 fprintf (e, "lockdir /usr/tmp/tstuu/spool1\n");
892 fprintf (e, "sysfile /usr/tmp/tstuu/System1\n");
893 fprintf (e, "sysfile /usr/tmp/tstuu/System1.2\n");
894 fprintf (e, "portfile /usr/tmp/tstuu/Port1\n");
895 (void) remove ("/usr/tmp/tstuu/Log1");
896 #if ! HAVE_HDB_LOGGING
897 fprintf (e, "logfile /usr/tmp/tstuu/Log1\n");
899 fprintf (e, "%s\n", "logfile /usr/tmp/tstuu/Log1/%s/%s");
901 fprintf (e, "statfile /usr/tmp/tstuu/Stats1\n");
902 fprintf (e, "debugfile /usr/tmp/tstuu/Debug1\n");
903 fprintf (e, "callfile /usr/tmp/tstuu/Call1\n");
904 fprintf (e, "pubdir /usr/tmp/tstuu\n");
906 fprintf (e, "v2-files no\n");
909 fprintf (e, "hdb-files no\n");
912 fprintf (e, "debug %s\n", zDebug);
916 e = xfopen ("/usr/tmp/tstuu/System1", "w");
918 fprintf (e, "# This file is ignored, to test multiple system files\n");
919 fprintf (e, "time never\n");
923 e = xfopen ("/usr/tmp/tstuu/System1.2", "w");
925 fprintf (e, "# First test system file\n");
926 fprintf (e, "time any\n");
927 fprintf (e, "port stdin\n");
928 fprintf (e, "# That was the defaults\n");
929 fprintf (e, "system %s\n", zsys);
934 eprog = xfopen ("/usr/tmp/tstuu/Chat1", "w");
936 /* Wait for the other side to open the port and flush input. */
937 fprintf (eprog, "sleep 2\n");
939 "echo password $1 speed $2 1>&2\n");
940 fprintf (eprog, "echo test1\n");
941 fprintf (eprog, "exit 0\n");
945 if (chmod ("/usr/tmp/tstuu/Chat1",
946 S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0)
948 perror ("chmod (/usr/tmp/tstuu/Chat1)");
952 fprintf (e, "chat-program /usr/tmp/tstuu/Chat1 \\P \\S\n");
954 fprintf (e, "chat word: \\P\n");
955 fprintf (e, "chat-fail login;\n");
956 fprintf (e, "call-login *\n");
957 fprintf (e, "call-password *\n");
960 fprintf (e, "chat \"\"\n");
961 fprintf (e, "call-transfer yes\n");
962 fprintf (e, "commands cat\n");
963 if (! fcall_uucico && iPercent == 0)
965 fprintf (e, "protocol-parameter g window 7\n");
966 fprintf (e, "protocol-parameter g packet-size 4096\n");
967 fprintf (e, "protocol-parameter j avoid \\377\n");
969 if (zProtocols != NULL)
970 fprintf (e, "protocol %s\n", zProtocols);
974 e = xfopen ("/usr/tmp/tstuu/Port1", "w");
976 fprintf (e, "port stdin\n");
977 fprintf (e, "type stdin\n");
981 e = xfopen ("/usr/tmp/tstuu/Call1", "w");
983 fprintf (e, "Call out password file\n");
984 fprintf (e, "%s test1 pass\\s1\n", zsys);
992 e = xfopen ("/usr/tmp/tstuu/Config2", "w");
994 fprintf (e, "# Second test configuration file\n");
995 fprintf (e, "nodename test2\n");
996 fprintf (e, "spool /usr/tmp/tstuu/spool2\n");
997 fprintf (e, "lockdir /usr/tmp/tstuu/spool2\n");
998 fprintf (e, "sysfile /usr/tmp/tstuu/System2\n");
999 (void) remove ("/usr/tmp/tstuu/Log2");
1000 #if ! HAVE_HDB_LOGGING
1001 fprintf (e, "logfile /usr/tmp/tstuu/Log2\n");
1003 fprintf (e, "%s\n", "logfile /usr/tmp/tstuu/Log2/%s/%s");
1005 fprintf (e, "statfile /usr/tmp/tstuu/Stats2\n");
1006 fprintf (e, "debugfile /usr/tmp/tstuu/Debug2\n");
1007 fprintf (e, "passwdfile /usr/tmp/tstuu/Pass2\n");
1008 fprintf (e, "pubdir /usr/tmp/tstuu\n");
1010 fprintf (e, "v2-files no\n");
1013 fprintf (e, "hdb-files no\n");
1016 fprintf (e, "debug %s\n", zDebug);
1020 e = xfopen ("/usr/tmp/tstuu/System2", "w");
1022 fprintf (e, "# Second test system file\n");
1023 fprintf (e, "system test1\n");
1024 fprintf (e, "called-login test1\n");
1025 fprintf (e, "request true\n");
1026 fprintf (e, "commands cat\n");
1027 if (zProtocols != NULL)
1028 fprintf (e, "protocol %s\n", zProtocols);
1030 eprog = xfopen ("/usr/tmp/tstuu/Chat2", "w");
1033 "echo port $1 1>&2\n");
1034 fprintf (eprog, "exit 0\n");
1038 if (chmod ("/usr/tmp/tstuu/Chat2",
1039 S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0)
1041 perror ("chmod (/usr/tmp/tstuu/Chat2");
1042 exit (EXIT_FAILURE);
1045 fprintf (e, "called-chat-program /bin/sh /usr/tmp/tstuu/Chat2 \\Y\n");
1046 fprintf (e, "time any\n");
1050 e = xfopen ("/usr/tmp/tstuu/Pass2", "w");
1052 fprintf (e, "# Call in password file\n");
1053 fprintf (e, "test1 pass\\s1\n");
1059 zuucp1 = "./uucp -I /usr/tmp/tstuu/Config1 -r";
1060 zuux1 = "./uux -I /usr/tmp/tstuu/Config1 -r";
1064 zuucp2 = "/usr/bin/uucp -r";
1065 zuux2 = "/usr/bin/uux -r";
1069 zuucp2 = "./uucp -I /usr/tmp/tstuu/Config2 -r";
1070 zuux2 = "./uux -I /usr/tmp/tstuu/Config2 -r";
1073 /* Test transferring a file from the first system to the second. */
1074 if (itest == 0 || itest == 1)
1076 zfrom = "/usr/tmp/tstuu/from1";
1078 zto = "/usr/spool/uucppublic/to1";
1080 zto = "/usr/tmp/tstuu/to1";
1082 (void) remove (zto);
1083 umake_file (zfrom, 0);
1085 sprintf (ab, "%s %s %s!%s", zuucp1, zfrom, zsys, zto);
1089 /* Test having the first system request a file from the second. */
1090 if (itest == 0 || itest == 2)
1093 zfrom = "/usr/spool/uucppublic/from2";
1095 zfrom = "/usr/tmp/tstuu/from2";
1096 zto = "/usr/tmp/tstuu/to2";
1098 (void) remove (zto);
1099 umake_file (zfrom, 3);
1101 sprintf (ab, "%s %s!%s %s", zuucp1, zsys, zfrom, zto);
1105 /* Test having the second system send a file to the first. */
1106 if (itest == 0 || itest == 3)
1109 zfrom = "/usr/spool/uucppublic/from3";
1111 zfrom = "/usr/tmp/tstuu/from3";
1112 zto = "/usr/tmp/tstuu/to3";
1114 (void) remove (zto);
1115 umake_file (zfrom, 5);
1117 sprintf (ab, "%s -c \\~/from3 test1!~/to3", zuucp2);
1121 /* Test having the second system request a file from the first. */
1122 if (itest == 0 || itest == 4)
1124 zfrom = "/usr/tmp/tstuu/from4";
1126 zto = "/usr/spool/uucppublic/to4";
1128 zto = "/usr/tmp/tstuu/to4";
1130 (void) remove (zto);
1131 umake_file (zfrom, 7);
1133 sprintf (ab, "%s test1!%s %s", zuucp2, zfrom, zto);
1137 /* Test having the second system make an execution request. */
1138 if (itest == 0 || itest == 5)
1140 zfrom = "/usr/tmp/tstuu/from5";
1142 zto = "/usr/spool/uucppublic/to5";
1144 zto = "/usr/tmp/tstuu/to5";
1146 (void) remove (zto);
1147 umake_file (zfrom, 11);
1149 sprintf (ab, "%s test1!cat '<%s' '>%s'", zuux2, zfrom, zto);
1153 /* Test having the first system request a wildcard. */
1154 if (itest == 0 || itest == 6)
1156 const char *zfrom1, *zfrom2;
1160 zfrom = "/usr/spool/uucppublic/to6\\*";
1161 zfrom1 = "/usr/spool/uucppublic/to6.1";
1162 zfrom2 = "/usr/spool/uucppublic/to6.2";
1166 zfrom = "/usr/tmp/tstuu/spool2/to6\\*";
1167 zfrom1 = "/usr/tmp/tstuu/spool2/to6.1";
1168 zfrom2 = "/usr/tmp/tstuu/spool2/to6.2";
1171 umake_file (zfrom1, 100);
1172 umake_file (zfrom2, 101);
1173 (void) remove ("/usr/tmp/tstuu/to6.1");
1174 (void) remove ("/usr/tmp/tstuu/to6.2");
1176 sprintf (ab, "%s %s!%s /usr/tmp/tstuu", zuucp1, zsys, zfrom);
1180 /* Test having the second system request a wildcard. */
1181 if (itest == 0 || itest == 7)
1183 const char *zto1, *zto2;
1187 zto = "/usr/spool/uucppublic";
1188 zto1 = "/usr/spool/uucppublic/to7.1";
1189 zto2 = "/usr/spool/uucppublic/to7.2";
1193 zto = "/usr/tmp/tstuu";
1194 zto1 = "/usr/tmp/tstuu/to7.1";
1195 zto2 = "/usr/tmp/tstuu/to7.2";
1198 umake_file ("/usr/tmp/tstuu/spool1/to7.1", 150);
1199 umake_file ("/usr/tmp/tstuu/spool1/to7.2", 155);
1200 (void) remove (zto1);
1201 (void) remove (zto2);
1203 sprintf (ab, "%s test1!/usr/tmp/tstuu/spool1/to7.\\* %s", zuucp2,
1208 /* Test an E command. This runs cat, discarding the output. */
1209 if ((itest == 0 || itest == 8) && ! fcall_uucico)
1211 umake_file ("/usr/tmp/tstuu/from8", 30);
1212 sprintf (ab, "%s - test2!cat < /usr/tmp/tstuu/from8", zuux1);
1217 /* Try to make sure the file transfers were successful. */
1220 ucheck_test (itest, fcall_uucico)
1222 boolean fcall_uucico;
1224 if (itest == 0 || itest == 1)
1227 ucheck_file ("/usr/spool/uucppublic/to1", "test 1", 0);
1229 ucheck_file ("/usr/tmp/tstuu/to1", "test 1", 0);
1232 if (itest == 0 || itest == 2)
1233 ucheck_file ("/usr/tmp/tstuu/to2", "test 2", 3);
1235 if (itest == 0 || itest == 3)
1236 ucheck_file ("/usr/tmp/tstuu/to3", "test 3", 5);
1238 if (itest == 0 || itest == 4)
1241 ucheck_file ("/usr/spool/uucppublic/to4", "test 4", 7);
1243 ucheck_file ("/usr/tmp/tstuu/to4", "test 4", 7);
1246 if (itest == 0 || itest == 6)
1248 ucheck_file ("/usr/tmp/tstuu/to6.1", "test 6.1", 100);
1249 ucheck_file ("/usr/tmp/tstuu/to6.2", "test 6.2", 101);
1252 if (itest == 0 || itest == 7)
1254 const char *zto1, *zto2;
1258 zto1 = "/usr/spool/uucppublic/to7.1";
1259 zto2 = "/usr/spool/uucppublic/to7.2";
1263 zto1 = "/usr/tmp/tstuu/to7.1";
1264 zto2 = "/usr/tmp/tstuu/to7.2";
1267 ucheck_file (zto1, "test 7.1", 150);
1268 ucheck_file (zto2, "test 7.2", 155);
1272 /* A debugging routine used when displaying buffers. */
1279 if (isprint (BUCHAR (ichar)) && ichar != '\"')
1299 sprintf (z, "%03o", (unsigned int)(ichar & 0xff));
1300 return strlen (z) + 1;
1304 /* Pick one of two file descriptors which is ready for reading, or
1305 return in five seconds. If the argument is ready for reading,
1306 leave it alone; otherwise set it to -1. */
1316 struct timeval stime;
1318 iread = (1 << *po1) | (1 << *po2);
1322 if (select ((*po1 > *po2 ? *po1 : *po2) + 1, (pointer) &iread,
1323 (pointer) NULL, (pointer) NULL, &stime) < 0)
1329 if ((iread & (1 << *po1)) == 0)
1332 if ((iread & (1 << *po2)) == 0)
1335 #else /* ! HAVE_SELECT */
1339 struct pollfd as[2];
1342 as[0].events = POLLIN;
1344 as[1].events = POLLIN;
1346 if (poll (as, 2, 5 * 1000) < 0)
1352 if ((as[0].revents & POLLIN) == 0)
1355 if ((as[1].revents & POLLIN) == 0)
1358 #endif /* HAVE_POLL */
1359 #endif /* ! HAVE_SELECT */
1362 /* Read some data from a file descriptor. This keeps reading until
1363 one of the reads gets no data. */
1368 struct sbuf **pqbuf;
1372 while (*pqbuf != NULL && (*pqbuf)->qnext != NULL)
1373 pqbuf = &(*pqbuf)->qnext;
1382 && (*pqbuf)->cend >= sizeof (*pqbuf)->ab)
1383 pqbuf = &(*pqbuf)->qnext;
1387 *pqbuf = (struct sbuf *) malloc (sizeof (struct sbuf));
1390 fprintf (stderr, "Out of memory\n");
1393 (*pqbuf)->qnext = NULL;
1394 (*pqbuf)->cstart = 0;
1398 cgot = read (o, (*pqbuf)->ab + (*pqbuf)->cend,
1399 (sizeof (*pqbuf)->ab) - (*pqbuf)->cend);
1402 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENODATA)
1423 zfrom = (*pqbuf)->ab + (*pqbuf)->cend;
1425 for (i = 0; i < cgot && i < 80; i++, zfrom++)
1426 zshow += cpshow (zshow, *zfrom);
1434 fprintf (stderr, "Read from %d: %d \"%s\"\n", o, cgot, abshow);
1444 for (i = 0; i < cgot; i++)
1446 if (rand () % 1000 < iPercent)
1448 ++(*pqbuf)->ab[(*pqbuf)->cend + i];
1452 if (zDebug != NULL && c > 0)
1453 fprintf (stderr, "Clobbered %d bytes\n", c);
1456 (*pqbuf)->cend += cgot;
1463 /* Write data to a file descriptor until one of the writes gets no
1467 fsend (o, oslave, pqbuf)
1470 struct sbuf **pqbuf;
1475 while (*pqbuf != NULL)
1479 if ((*pqbuf)->cstart >= (*pqbuf)->cend)
1484 *pqbuf = (*pqbuf)->qnext;
1485 free ((pointer) qfree);
1493 if (ioctl (oslave, FIONREAD, &cunread) < 0)
1495 perror ("FIONREAD");
1499 fprintf (stderr, "%ld unread\n", cunread);
1500 cwrite = 256 - cunread;
1504 #else /* ! FIONREAD */
1505 if (! fwritable (o))
1508 #endif /* ! FIONREAD */
1510 if (cwrite > (*pqbuf)->cend - (*pqbuf)->cstart)
1511 cwrite = (*pqbuf)->cend - (*pqbuf)->cstart;
1513 cwrote = write (o, (*pqbuf)->ab + (*pqbuf)->cstart, cwrite);
1516 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENODATA)
1529 (*pqbuf)->cstart += cwrote;
1532 if (zDebug != NULL && ctotal > 0)
1533 fprintf (stderr, "Wrote %ld to %d\n", ctotal, o);
1538 /* Check whether a file descriptor can be written to. */
1547 struct timeval stime;
1555 cfds = select (o + 1, (pointer) NULL, (pointer) &iwrite,
1556 (pointer) NULL, &stime);
1565 #else /* ! HAVE_SELECT */
1575 cfds = poll (&s, 1, 0);
1584 #endif /* HAVE_POLL */
1585 #endif /* ! HAVE_SELECT */
1588 /* A version of the system command that checks for errors. */
1596 istat = system ((char *) zcmd);
1599 fprintf (stderr, "Command failed with status %d\n", istat);
1600 fprintf (stderr, "%s\n", zcmd);
1601 exit (EXIT_FAILURE);