]> diplodocus.org Git - nmh/blob - docs/historical/SRI-NOSC/send.c
Added start_test/finish_test to a bunch of tests.
[nmh] / docs / historical / SRI-NOSC / send.c
1 #include "mh.h";
2 #include "iobuf.h"
3 #include "stat.h"
4
5 #define DEBUG 1 /* Comment out normally */
6 #define TIMJUL 1
7 #define TIMSECS 2
8 #define TIMREG 3
9
10 /* Include a -msgid switch to .mh_defs to cause a
11 * Message-Id component to be added to outgoing mail.
12 */
13
14 char *anoyes[], /* Std no/yes gans array */
15 draft[],
16 locname[], /* local host name */
17 sbmitloc[], /* location (pathname) of submit process */
18 sbmitnam[]; /* name of submit process */
19 struct swit switches[]
20 {
21 "debug", -1, /* 0 */
22 "draft", 0, /* 1 */
23 "format", 0, /* 2 */
24 "noformat", 0, /* 3 */
25 "msgid", 0, /* 4 */
26 "nomsgid", 0, /* 5 */
27 "verbose", 1, /* 6 *//* DBG dhc */
28 "noverbose", 0, /* 7 */
29 "help", 4, /* 8 */
30 0, 0
31 };
32 struct iobuf in,
33 pin,
34 pout,
35 fout,
36 fccout;
37 int errno;
38 int format 0; /* re-formatting is the default */
39 int sbmitfd[2];
40 int sbchild;
41
42 char *logn,
43 *parptr,
44 *nmsg,
45 fccfile[256],
46 sberrline[256];
47
48 main (argc, argv)
49 char *argv[];
50 {
51 int debug;
52 register char *cp;
53 register int state;
54 char *to,
55 *cc,
56 *bcc,
57 *dist_to,
58 *dist_cc,
59 *dist_bcc;
60 char *tolist,
61 *cclist,
62 *adrlist,
63 *sender,
64 *fieldptr,
65 *fcc,
66 *dist_fcc;
67 char msg[128];
68 char name[NAMESZ],
69 field[512];
70 int specfld,
71 dist,
72 fcconly;
73 int from,
74 loc,
75 net,
76 verbose,
77 msgid;
78 char *ap,
79 inp;
80 char *arguments[50],
81 **argp;
82
83 fout.b_fildes = dup (1);
84 msgid = from = loc = net = to = cc = bcc = dist = fcc = dist_fcc =
85 dist_to = dist_cc = dist_bcc = fcconly = debug = 0;
86
87 loc = net = 1; /* DBG during testing of new submit */
88
89 state = FLD;
90 msg[0] = 0;
91 ap = cp = argv[0];
92 while(*cp)
93 if(*cp++ == '/')
94 ap = cp;
95 inp = ap;
96 copyip (argv + 1, arguments);
97 argp = arguments;
98 while (cp = *argp++)
99 {
100 if (*cp == '-')
101 switch (smatch (++cp, switches))
102 {
103 case -2:
104 ambigsw (cp, switches);
105 /* ambiguous */
106 leave ("Illegal switch setting: \"%s\"", --cp);
107 /* unknown */
108 case -1:
109 leave ("-%s unknown", cp);
110 case 0:
111 verbose++;
112 debug++;
113 continue; /* -debug */
114 case 1:
115 copy (m_maildir (draft), msg);
116 continue; /* -draft */
117 case 2:
118 /* disabled for now format = 1; */
119 continue; /* -format */
120 case 3:
121 format = 0;
122 continue; /* -noformat */
123 case 4:
124 msgid = 1;
125 continue; /* -msgid */
126 case 5:
127 msgid = 0;
128 continue; /* -nomsgid */
129 case 6:
130 loc = 1;
131 net = 1;
132 continue; /* -verbose */
133 case 7:
134 loc = 0;
135 net = 0;
136 continue; /* -noverbose */
137 case 8:
138 help (concat( inp, " [file] [switches]", 0),
139 switches);
140 leave (0);
141 }
142 if (msg[0])
143 leave ("Only one message at a time!");
144 else
145 copy (cp, msg);
146 }
147 if (msg[0] == 0)
148 {
149 copy (m_maildir (draft), msg);
150 if (stat (msg, &field) == -1)
151 {
152 printf ("Draft file: %s doesn't exist.\n", msg);
153 flush ();
154 exit (1);
155 }
156 /* cp = concat ("Use \"", msg, "\"? ", 0);
157 if (!gans (cp, anoyes))
158 exit (0); */
159 }
160 if (fopen (msg, &in) < 0)
161 leave ("Can't open \"%s\" for reading.", msg);
162
163 state = FLD;
164
165 if (!loc && !net)
166 printf ("Message being processed...\n");
167 flush ();
168 for (;;)
169 switch (state = m_getfld (state, name, field, sizeof field, &in))
170 {
171
172 case FLD:
173 case FLDEOF:
174 case FLDPLUS:
175 if (!dist && field[0] != 'n' && uleq (name, "to"))
176 to = adrlist = add (field, adrlist);
177 else
178 if (!dist && field[0] != 'n' && uleq (name, "cc"))
179 cc = adrlist = add (field, adrlist);
180 else
181 if (!dist && uleq (name, "bcc"))
182 adrlist = add (field, adrlist);
183 else
184 if (!dist && uleq (name, "fcc"))
185 fcc = add (field, fcc);
186 else
187 if (field[0] != 'n' && uleq (name, "distribute-to"))
188 {
189 dist++;
190 /* use presence of field as flag */
191 to = adrlist = add (field, adrlist);
192 }
193 else
194 if (field[0] != 'n' && uleq (name, "distribute-cc"))
195 cc = adrlist = add (field, adrlist);
196 else
197 if (field[0] != 'n' && uleq (name, "distribute-bcc"))
198 adrlist = add (field, adrlist);
199 else
200 if (uleq (name, "distribute-fcc"))
201 dist_fcc = add (field, dist_fcc);
202 else
203 if (uleq (name, "from"))
204 from++;
205
206 if (state != FLDEOF)
207 continue;
208 case BODY:
209 case BODYEOF:
210 goto done;
211
212 default:
213 leave ("getfld returned %d", state);
214 }
215 done:
216 if (dist)
217 {
218 /* to = dist_to; */
219 /* cc = dist_cc; */
220 /* bcc = dist_bcc; */
221 fcc = dist_fcc;
222 }
223 if (!(to || cc))
224 if (!fcc)
225 leave ("Message %s has no addresses!!", msg);
226 else
227 fcconly++;
228 /****/ pin.b_fildes = dup (2);
229 /**** pout.b_fildes = 3;*/
230
231 /* if ((to && parse (to, 'c')) || */
232 /* (cc && parse (cc, 'c')) || */
233 /* (bcc && parse (bcc, 'c')) */
234 /* leavit (); */
235
236 /* parptr = adrlist; */
237 /* compress (); */
238 /* adrlist = parptr; */
239 parptr = 0;
240 if (verbose)
241 {
242 printf ("Address List:\n%s", adrlist);
243 flush ();
244 }
245
246 /* if (to && parse (to, 'r', dist ? "Distribute-To: " : "To: ")) */
247 /* leave (0); */
248 /* tolist = parptr; */
249 /* parptr = 0; */
250 /* if (cc && parse (cc, 'r', dist ? "Distribute-cc: " : "cc: ")) */
251 /* leave (0); */
252 /* cclist = parptr; */
253 /* parptr = 0; */
254 /* */
255 /* if (verbose) */
256 /* { */
257 /* if (tolist) */
258 /* printf (tolist); */
259 /* if (cclist) */
260 /* printf (cclist); */
261 /* flush (); */
262 /* } */
263 if (fcc)
264 {
265 if (*fcc == ' ')
266 fcc++;
267 for (cp = fcc; *cp && *cp != '\n'; cp++);
268 *cp = 0;
269 if (debug)
270 printf ("fcc: \"%s\"\n", fcc);
271 flush ();
272 if ((fccout.b_fildes = filemsg (fcc)) == -1)
273 leave ("Problem beginning fcc message transfer");
274 }
275
276 /* if (parse (field, 'r', dist ? "Distributed-By: " */
277 /* : (from ? "Sender: " : "From: "))) */
278 /* leave (0); */
279
280 sender = add ((dist) ? "Distributed-By: "
281 : (from) ? "Sender: "
282 : "From: ", sender);
283 fieldptr = copy ((logn = getlogn (getruid ())), field);
284 fieldptr = copy (" at ", fieldptr);
285 fieldptr = copy ( locname, fieldptr);
286 copy ( "\n", fieldptr);
287 sender = add (field, sender);
288 /* parptr = 0; */
289 seek (in.b_fildes, 0, 0);
290 /* *** INVOKE SUBMIT, AT LAST *** */
291 ap = arguments;
292 *ap++ = '-'; /* indicate a switch sequence
293 */
294 /* *ap++ = 'd'; /*DBG have submit output messages */
295 *ap++ = 'm'; /* mail, not screen-notice, yet
296 */
297 /* cputc ('s', &pout); */
298 /* ******* During initial testing, mail always sent immediately, ****** */
299 /* so that users can verify delivery... */
300 /* Can't trust new software these days... ****** */
301
302 /* if (loc) */
303 *ap++ = 'l'; /* send local mail now */
304 if (net)
305 *ap++ = 'n'; /* send net mail now */
306 if (net || loc)
307 *ap++ = 'w'; /* user will watch deliveries */
308
309 /* ******* * * * * * * * * * * * * * * * * * * * * * * * * * * ****** */
310
311 *ap++ = 'r'; /* return messages go to sender
312 */
313 *ap = '\0';
314
315 if (debug)
316 pout.b_fildes = 1; /* Send msg to std output for debugging */
317 else
318 if (fcconly)
319 pout.b_fildes = 0; /* Flush send output if only an fcc */
320 else
321 {
322 if ((sbchild = sbmitinit (arguments, sbmitfd)) == -1)
323 leave ("Unable to invoke submit");
324 pout.b_fildes = sbmitfd[1];
325 }
326
327 puts (adrlist, &pout);
328 puts ("!\n", &pout); /* end the address list */
329 puts2 (sender, &pout);
330 puts2 (dist ? "Distribution-Date: " : "Date: ", &pout);
331 puts2 (cnvtdate (TIMREG), &pout);
332 puts2 ("\n", &pout);
333 if (msgid)
334 {
335 puts2 (dist ? "Distribution-ID: " : "Message-ID: ", &pout);
336 puts2 ("<", &pout);
337 puts2 (cnvtdate (TIMJUL), &pout);
338 puts2 (".", &pout);
339 puts2 (locv (0, getpid ()), &pout);
340 puts2 (" at ", &pout);
341 puts2 (locname, &pout);
342 puts2 ("\n", &pout);
343 }
344 seek (in.b_fildes, 0, 0);
345 in.b_nleft = in.b_nextp = 0;
346 state = FLD;
347 for (;;)
348 switch (state = m_getfld (state, name, field, sizeof field, &in))
349 {
350 case FLD:
351 case FLDEOF:
352 case FLDPLUS:
353 specfld = 0;
354 if (format && uleq (name, dist ? "distribute-to" : "to"))
355 {
356 specfld++;
357 if (tolist)
358 puts2 (tolist, &pout);
359 }
360 else
361 if (format && uleq (name, dist ? "distribute-cc" : "cc"))
362 {
363 specfld++;
364 if (cclist)
365 puts2 (cclist, &pout);
366 }
367 else
368 if (uleq (name, dist ? "distribute-bcc" : "bcc") ||
369 uleq (name, dist ? "distributed-by" : "sender") ||
370 uleq (name, dist ? "distribution-date" : "date") ||
371 uleq (name, dist ? "distribution-id" : "message-id") ||
372 uleq (name, dist ? "distribution-fcc" : "fcc"))
373 specfld++;
374 /* Ignore these if present */
375 else
376 {
377 puts2 (name, &pout);
378 puts2 (":", &pout);
379 puts2 (field, &pout);
380 }
381 while (state == FLDPLUS)
382 { /* read rest of field */
383 state = m_getfld (state, name, field, sizeof field, &in);
384 if (specfld)
385 continue;
386 /* puts2(name, &pout); puts2(":", &pout); */
387 puts2 (field, &pout);
388 }
389 if (state == FLDEOF)
390 goto endit;
391 continue;
392 case BODY:
393 case BODYEOF:
394 if (field[0])
395 {
396 puts2 ("\n", &pout);
397 puts2 (field, &pout);
398 }
399
400 while (state == BODY)
401 {
402 state = m_getfld (state, name, field, sizeof field, &in);
403 puts2 (field, &pout);
404 }
405 if (state == BODYEOF)
406 goto endit;
407 default:
408 leave ("Error from getfld=%d", state);
409 }
410
411 endit:
412 errno = 0;
413 if (pout.b_fildes)
414 if (fflush (&pout) < 0 || errno != 0)
415 leave ("Problem writing data to Submit.");
416 if (fccout.b_fildes)
417 {
418 fflush (&fccout);
419 close (fccout.b_fildes);
420 }
421 if (!debug && !fcconly)
422 {
423 /* if ((state = read (2, &field, sizeof field)) != 1 || field[0]) */
424 if (loc || net)
425 {
426 printf ("Delivery being attempted...\n");
427 flush ();
428 }
429 if (sbresp (&sbmitfd) != 0)
430 leave ("Mail submission program ended abnormally");
431 }
432 if (fccout.b_fildes)
433 printf ("Filed: %s:%s\n", fcc, nmsg);
434 if (!debug)
435 {
436 if (!fcconly)
437 {
438 printf ("Message processed.\n");
439 /* printf ("Message %s processed.\n", msg);*/
440 flush ();
441 }
442 cp = copy (msg, field);
443 /* for(cp = field; *cp++; ) ; */
444 cp[1] = 0;
445 do
446 *cp = cp[-1];
447 while (--cp >= field && *cp != '/');
448 *++cp = ','; /* New backup convention */
449 unlink (field);
450 if (link (msg, field) == -1 || unlink (msg) == -1)
451 printf ("Can't rename %s to %s\n", msg, field);
452 }
453 m_update ();
454 /* childend (); */
455 flush ();
456 exit (0);
457 }
458
459 leave (form, a1, a2, a3)
460 char *form,
461 *a1,
462 *a2,
463 *a3;
464 {
465 if (form != 0)
466 {
467 printf (form, a1, a2, a3);
468 putchar ('\n');
469 }
470 if (sbchild != 0)
471 kill (sbchild, 9);
472 printf ("[ Message NOT Delivered! ]\n");
473 if (fccout.b_fildes)
474 unlink (fccfile);
475 m_update ();
476 flush ();
477 exit (1);
478 }
479
480 parse (ptr, type, fldname)
481 char *fldname;
482 {
483 register int i;
484 register int l;
485 char line[128];
486
487 errno = 0;
488 putc (type, &pout);
489 puts ("\n", &pout);
490 puts (ptr, &pout);
491 if (fflush (&pout) < 0 || errno != 0)
492 leave ("Problem sending data to Submit.");
493 write (pout.b_fildes, "", 1);
494 l = 0;
495
496 while ((i = getl (&pin, line, (sizeof line) - 1)) > 0)
497 {
498 line[i] = 0;
499 if (line[0] == 0)
500 {
501 if (type == 'r')
502 {
503 if (l > 0)
504 parptr = add ("\n", parptr);
505 }
506 return (0);
507 }
508 else
509 if (line[0] == '?')
510 {
511 printf ("Submit returned: %s", line);
512 return (1);
513 }
514 if (type == 'r')
515 {
516 line[--i] = 0;
517 if (l + i > 70)
518 {
519 parptr = add ("\n", parptr);
520 l = 0;
521 }
522 if (l == 0)
523 {
524 parptr = add (fldname, parptr);
525 l =+ length (fldname);
526 }
527 else
528 {
529 parptr = add (", ", parptr);
530 l =+ 2;
531 }
532 parptr = add (line + 1, parptr);
533 l =+ i;
534 }
535 else
536 parptr = add (line, parptr);
537 }
538 printf ("Error from Submit.\n");
539 return (1);
540 }
541
542 cnvtdate (flag)
543 int flag; /* date format option value */
544 {
545 static char datbuf[128];
546 extern int daylight;
547 int tvec[2];
548 long int seconds;
549 register int
550 *i;
551 register char
552 *p,
553 *t;
554
555 time (tvec);
556 i = localtime (tvec);
557 t = ctime (tvec);
558 p = datbuf;
559
560 switch (flag)
561 {
562 case TIMJUL: /* Julian-oriented for msg-ids */
563 for (itoa (i[5], p); *p; p++);
564 *p++ = '.';
565 for (itoa (i[7], p); *p; p++);
566 *p++ = '.';
567 seconds = i[2];
568 seconds = i[0] + (i[1] * 60) + (seconds * 3600);
569 litoa (seconds, p); /* seconds since midnight */
570 break;
571 case TIMREG: /* RFC 733 standard time string */
572 default: /* "Sat, 21 Jan 76 14:30-PDT" */
573 *p++ = t[0];
574 *p++ = t[1];
575 *p++ = t[2];
576 *p++ = ',';
577 *p++ = ' ';
578 *p++ = t[8]; /* day of month */
579 *p++ = t[9];
580 *p++ = ' ';
581 *p++ = t[4]; /* month abbreviation eg: "JAN" */
582 *p++ = t[5];
583 *p++ = t[6];
584 *p++ = ' ';
585 *p++ = t[22]; /* year eg: "76" */
586 *p++ = t[23];
587 *p++ = ' ';
588 *p++ = t[11]; /* hours & minutes eg: "14:30" */
589 *p++ = t[12];
590 *p++ = ':';
591 *p++ = t[14];
592 *p++ = t[15];
593 *p++ = '-';
594 *p++ = 'P'; /* time zone eg: "PDT" */
595 *p++ = (i[8]) ? 'D' : 'S';
596 *p++ = 'T';
597 *p++ = '\000';
598 }
599 free (i);
600 free (t);
601 return (datbuf);
602 }
603
604 getl (iob, buf, size)
605 {
606 register char *cp;
607 register int cnt,
608 c;
609
610 for (cp = buf, cnt = size; (c = getc (iob)) >= 0;)
611 {
612 *cp++ = c;
613 --cnt;
614 switch (c)
615 {
616 case '\0':
617 case '\n':
618 break;
619 default:
620 continue;
621 }
622 break;
623 }
624 return (size - cnt);
625 }
626
627 compress ()
628 {
629 register char *f1,
630 *f2,
631 *f3;
632
633 #ifdef DEBUG
634 printf ("compress:\n%s-----\n", parptr);
635 #endif
636 for (f1 = parptr; *f1;)
637 {
638 for (f2 = f1; *f2++ != '\n';);
639 while (*f2)
640 {
641 if (eqqq (f1, f2))
642 {
643 for (f3 = f2; *f3++ != '\n';);
644 copy (f3, f2);
645 }
646 else
647 while (*f2++ != '\n');
648 }
649 while (*f1++ != '\n');
650 }
651 }
652
653 eqqq (s1, s2)
654 {
655 register char *c1,
656 *c2;
657
658 c1 = s1;
659 c2 = s2;
660 while (*c1 != '\n' && *c2 != '\n')
661 if (*c1++ != *c2++)
662 return (0);
663 return (*c1 == *c2);
664 }
665 filemsg (folder)
666 char *folder;
667 {
668 register int i;
669 register char *fp;
670 struct inode stbuf;
671 struct msgs *mp;
672
673 fp = m_maildir (folder);
674 if (stat (fp, &stbuf) < 0)
675 {
676 /* nmsg = concat ("Create folder \"",
677 fp, "\"? ", 0);
678 if (!gans (nmsg, anoyes))
679 return (-1); */
680 if (!makedir (fp))
681 {
682 printf ("Can't create folder.\n");
683 return (-1);
684 }
685 }
686 if (chdir (fp) < 0)
687 {
688 perror (concat ("Can't chdir to ", fp, 0));
689 return (-1);
690 }
691 if (!(mp = m_gmsg ()))
692 {
693 printf ("Can't read folder %s\n", folder);
694 return (-1);
695 }
696 nmsg = m_name (mp -> hghmsg + 1);
697 copy (nmsg, copy ("/", copy (m_maildir (fp), fccfile)));
698 if ((i = creat (fccfile, m_gmprot ())) == -1)
699 printf ("Can't create %s\n", fccfile);
700 return (i);
701 }
702
703 puts2 (str, iob)
704 {
705 puts (str, &fccout);
706 errno = 0;
707 puts (str, iob);
708 if (fflush (iob) < 0 || errno != 0)
709 leave ("Problem writing out data");
710 }
711 /* subroutines to interface to submit */
712
713 #define CLOSEFD -1 /* if equals fdarray[i], close (i); */
714 #define PUREXEC 0 /* simply exec over current process */
715 #define FRKEXEC 1 /* run it in lower process */
716 #define SPNEXEC 2 /* separate new process from old */
717 #define FRKWAIT 1 /* wait for FRKEXEC to complete */
718 #define FRKPIGO 2 /* Parent's signals off during FRKWAIT */
719 #define FRKCIGO 4 /* Childs signals off before execl */
720 /*#define EXECR 8 ** Use execr, instead of execv */
721 #define HIGHFD 16
722 #define NUMTRY 30
723
724 struct pstruct
725 {
726 int prd;
727 int pwrt;
728 };
729 int highfd
730 {
731 HIGHFD
732 };
733 int regfdary[]
734 {
735 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
736 -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
737 };
738
739 sbmitinit (args, ioary)
740 char *args;
741 int *ioary;
742 {
743
744 struct pstruct sbpout;
745 int sbmitid;
746 char linebuf[256];
747 char *p;
748
749 if (pipe (&sbpout) == -1)
750 return (-1);
751 regfdary[0] = sbpout.prd;
752 regfdary[1] = fout.b_fildes;
753
754 if ((sbmitid = newpgml (FRKEXEC, 0, regfdary,
755 sbmitloc, sbmitnam, args, 0)) == -1)
756 {
757 flush ();
758 close (sbpout.prd);
759 close (sbpout.pwrt);
760 return (-1);
761 }
762
763 dbglog ("Ready to close");
764 close (sbpout.prd);
765 ioary[1] = sbpout.pwrt;
766 return (sbmitid);
767 }
768
769 #ifdef COMMNET
770 sbmitadr (name, ioary)
771 char *name;
772 int *ioary;
773 {
774 int tmp;
775 char linebuf[256];
776 char *from,
777 *to;
778
779 for (from = name, to = linebuf; *to = *from++; to++);
780 for (from = "\n"; *to++ = *from++;);
781 tmp = to - &linebuf;
782
783 if (write (ioary[1], linebuf, tmp) == -1)
784 return (-1);
785
786 return (sbresp (ioary));
787 }
788 #endif
789
790 sbresp (ioary)
791 int *ioary;
792 {
793 return (childend ());
794 }
795
796 newpgml (proctyp, pgmflags, fdarray, pgm, pgmparm)
797 int proctyp,
798 pgmflags,
799 fdarray[];
800 char *pgm,
801 *pgmparm;
802 {
803 int retval;
804 char *parmptr;
805 /* printf ("newpgml: calling newpgmv\n"); */
806 parmptr = &pgmparm;
807 retval = newpgmv (proctyp, pgmflags, fdarray, pgm, parmptr);
808 return (retval);
809 }
810
811 newpgmv (proctyp, pgmflags, fdarray, pgm, pgmparm)
812 int proctyp,
813 pgmflags,
814 fdarray[];
815 char *pgm,
816 *pgmparm[];
817 {
818 register int tmp;
819 int tmp2;
820 int childid;
821 int tried;
822 int osig[3];
823
824 if (proctyp != PUREXEC)
825 {
826 /* printf ("This is a forking call.\n"); */
827 for (tried = NUMTRY; (childid = fork ()) == -1 && tried--; sleep (1));
828 if (childid == -1)
829 return (-1);
830 /* printf ("Successful fork\n"); */
831 if (childid != 0)
832 { /* parent process */
833 if (pgmflags & FRKPIGO)
834 { /* disable parent signals */
835 /* printf ("Parent to be
836 non-interruptible\n"); */
837 osig[0] = signal (1, 1);
838 osig[1] = signal (2, 1);
839 osig[2] = signal (3, 1);
840 }
841 if ((proctyp == FRKEXEC) && (pgmflags & FRKWAIT))
842 {
843 /* printf ("Parent is to wait\n"); */
844 while ((tmp = wait (&tmp2)) != childid && tmp != -1);
845 /* printf ("Parent done waiting\n"); */
846 if (pgmflags & FRKPIGO)
847 {
848 signal (1, osig[0]);
849 signal (2, osig[1]);
850 signal (3, osig[2]);
851 }
852 return (tmp2);
853 }
854 return (childid);
855 }
856 if (proctyp == SPNEXEC)
857 { /* want it to be a spawn */
858 /* printf ("This is a spawn\n"); */
859 for (tried = NUMTRY; (tmp = fork ()) < 0 && tried--;
860 sleep (1));
861 if (tmp != 0) /* split the grandparent from the */
862 exit (tmp < 0 ? -2 : 0);
863 /* grandchild: kill middle proc */
864 }
865 }
866 if (fdarray)
867 { /* re-align fd array list */
868 fout.b_fildes = fdarray[1];
869 for (tmp = 0; tmp < highfd; tmp++)
870 { /* first do the re-positions */
871 if (fdarray[tmp] != CLOSEFD && fdarray[tmp] != tmp)
872 {
873 dbglog ("Closing %2d\n", tmp);
874 flush ();
875 close (tmp);
876 while ((tmp2 = dup (fdarray[tmp])) < tmp && tmp2 != -1);
877 dbglog ("Last dup'd %d into %d\n", fdarray[tmp], tmp2);
878 flush ();
879 /* did we get right fd? */
880 }
881 }
882 for (tmp = 0; tmp < highfd; tmp++)
883 if (fdarray[tmp] == CLOSEFD)
884 {
885 dbglog ("Closing %2d\n", tmp);
886 flush ();
887 close (tmp); /* get rid of unwanted ones */
888 }
889 }
890 fout.b_fildes = 1;
891
892 if (pgmflags & FRKCIGO)
893 {
894 /* printf ("Child's interrupts to be
895 disabled\n"); */
896 signal (1, 1);
897 signal (2, 1);
898 signal (3, 1);
899 }
900
901 /* printf ("Execing %s\n", pgm); */
902 /* if (pgmflags & EXECR) */
903 /* execr (pgm, pgmparm); */
904 /* else */
905 execv (pgm, pgmparm);
906 /* printf ("Exec not successful\n"); */
907 if (proctyp == PUREXEC)
908 return (-1);
909 fout.b_fildes = 1;
910 printf ("Unable to exec \"%s\"\n", pgm);
911 flush ();
912 for (tmp = 0; tmp < 20 && pgmparm[tmp][0] != 0 ; tmp++)
913 {
914 printf ("Parm %d = \"%s\"\n", tmp, pgmparm[tmp]); flush ();
915 }
916 exit (-3);
917 }
918
919 childend ()
920 {
921 int tmp,
922 tmp2;
923
924 /* close (sbmitfd[0]); */
925 close (sbmitfd[1]);
926 while ((tmp = wait (&tmp2)) != sbchild && tmp != -1);
927 return (tmp2 >> 8);
928 }
929 dbglog (str)
930 {
931 return;
932 printf(str);
933 }