#-h- bdsh.c 3377 asc 02-dec-82 10:51:46 sventek (joseph sventek) #include #define DEFAULT_PATH ":/bin/:/usr/bin/" #define IMAGE_SUFFIX ".exe" char search_path[200], *arg_array[100], buffer[512], ex_image[100]; main(argc, argv) int argc; char *argv[]; { FILE *fin, *fopen(); char *fgets(); char local_path[200]; if (argc == 1 || strcmp("-", argv[1]) == 0) fin = stdin; else if ((fin = fopen(argv[1], "r")) == NULL) f_error("Unable to open input file %s\n", argv[1]); if (argc < 3) strcpy(search_path, DEFAULT_PATH); else strcpy(search_path, argv[2]); while (fgets(buffer, 512, fin) != NULL) { fmt_args(buffer, arg_array); if (arg_array[0] == (char *)0) continue; strcpy(local_path, search_path); if (loc_cmd(arg_array[0], local_path, ex_image) == 0) { fprintf(stderr, "Unable to locate `%s'", arg_array[0]); f_error(" along search path `%s'\n", search_path); } if (spawn(ex_image, arg_array) == 0) f_error("Error spawning %s\n", ex_image); } exit(0); } f_error(fmt, str) char *fmt, *str; { fprintf(stderr, fmt, str); exit(1); } fmt_args(buf, args) char *buf, *args[]; { char *s, qu_ch, c; int i; s = buf; for (i = 0; ; ) { while (*s == ' ' || *s == '\t') s++; if (*s == '\n' || *s == '\0') break; if (*s == '"' || *s == '\'') qu_ch = *s++; else qu_ch = '\0'; args[i] = s; for (c = *s; c != '\n' && c != '\0'; c = *(++s)) { if (qu_ch == '\0') { if (c == ' ' || c == '\t') break; } else if (c == qu_ch) break; } *s++ = '\0'; i++; if (c == '\n' || c == '\0') break; } args[i] = (char *)0; } loc_cmd(file, path, image) char *file, *path, *image; { char *s, *out; FILE *fd, *fopen(); s = path; while (*s != '\0') { out = image; while (*s != ':' && *s != '\0') *out++ = *s++; if (*s == ':') s++; strcpy(out, file); /* try /directory/name */ if ((fd = fopen(image, "r")) != NULL) { fclose(fd); printf("file `%s' resolves into image `%s'\n", file, image); return(1); } strcat(image, IMAGE_SUFFIX); /* try /directory/name.extension */ if ((fd = fopen(image, "r")) != NULL) { fclose(fd); printf("file `%s' resolves into image `%s'\n", file, image); return(1); } } return(0); } spawn(image, args) char *image, *args[]; { int pid, status; int i, j; char *s, access[2], *index(); FILE *freopen(); if ((pid = vfork()) == 0) { for (i = 0, j = 0; args[i] != (char *)0; i++) { s = args[i]; if (index(args[i], '<') == args[i]) { s++; if (freopen(s, "r", stdin) != stdin) f_error("Error re-opening stdin to %s\n", s); } else if (index(args[i], '>') == args[i]) { s++; if (*s == '>') { strcpy(access, "a"); s++; } else strcpy(access, "w"); if (freopen(s, access, stdout) != stdout) f_error("Error re-opening stdout to %s\n", s); } else args[j++] = args[i]; } args[j] = (char *)0; execv(image, args); fprintf("Error exec'ing `%s'\n", image); exit(1); } else while (wait(status) != pid) ; return(1); } #-h- rmail.c 852 asc 02-dec-82 10:51:48 sventek (joseph sventek) #include char temp_file[64]; char buf[512]; char command[512]; main(argc, argv) int argc; char *argv[]; { char *p, index(); int system(); int fd, creat(), n, read(), write(); int pid, getpid(); if (index(argv[1], '!')) { execl("/usr/rmail", "rmail", argv[1], 0); fprintf(stderr, "Execl of /usr/rmail failed\n"); exit(1); } pid = getpid(); sprintf(temp_file, "/tmp/f%08x.rml", pid); if ((fd = creat(temp_file, 0777, "txt")) == -1) { fprintf(stderr, "rmail: cannot create temp file.\n"); exit(1); } while ((n = read(0, buf, 512)) > 0) write(fd, buf, n); close(fd); sprintf(command, "@st_usr:st uucptomsg %s tmp:f%08x.rml ??~msg/u2m.log", argv[1], pid); if (! system(command)) { fprintf(stderr, "Error spawning '%s'\n", command); exit(1); } exit(0); } #-h- system.mar 6159 asc 29-jul-82 09:51:23 tools (lblh csam sventek) .title system .sbttl comments and symbol definitions ;+ ; integer function system(buffer) ; ; character buffer(ARB) ; ; return(0/1) if spawn failed/succeeded ; ; the EOS-terminated command in buffer is spawned to the local ; command interpreter (DCL). If the spawn succeeded, a value of ; 1 is returned, else 0. If buffer contains a null command, a ; value of 1 is returned. ; ; sys$system:loginout.exe is spawned as a sub-process reading ; a mailbox for its input. After some preliminary DCL commands ; to force the environment to be correct, the command in buffer ; is executed as ; ; @st_bin:dodcl/out='term' 'command' ; ; where 'term' is replaced by the translation of TT and 'command' ; is the user specified command. This command procedure is ; designed to perform some more hacks to get the environment in ; shape and to define the tools as foreign symbols. ;- $jpidef $dibdef $accdef $pqldef $devdef buffer=4 .page .sbttl impure data ; ; impure data ; pid: .blkl 1 ; our pid goes here prib: .blkl 1 ; our base priority goes here authpr: .blkq 1 ; our authorization privelege mask goes here pidbuf: .blkb 8 ; buffer for formatted pid trmbuf: .ascii "SYSTRM" ; name of termination mailbox trmpid: .blkb 8 ; ... argbuf: .ascii "SYSARG" ; name of argument mailbox argpid: .blkb 8 ; ... prcbuf: .ascii "SYS" ; sub-process name prcpid: .blkb 8 ; ... trmchn: .blkw 1 ; space for termination mailbox channel trmunt: .blkw 1 ; space for termination mailbox unit buf: .blkb 512 ; termporary buffer ttybuf: .blkb 64 ; buffer for TT translation dumdsc: .blkq 1 ; dummy descriptor ttydsc: .long 64 ; resultant buffer for trnlog of TT .long ttybuf ; ... length: .blkw 1 ; location for length cmddsc: .blkq 1 ; command descriptor argchn: .blkw 1 ; location for argument mailbox channel trmsts: .blkb acc$k_termlen ; termination mbox message buffer .page .sbttl pure data ; ; pure data ; jpilst: .word 4,jpi$_pid ; fetch our pid .long pid,0 ; .. .word 4,jpi$_prib ; fetch our base priority .long prib,0 ; ... .word 8,jpi$_authpriv ; fetch our auth privelege mask .long authpr,0 ; ... .long 0 ; end of jpi list pidfmt: .ascid "!XL" ; format string for pid format trmdsc: .long 14 ; descriptor for termination mailbox .long trmbuf ; ... argdsc: .long 14 ; descriptor for argument mailbox .long argbuf ; ... prcdsc: .long 11 ; descriptor for process name .long prcbuf ; ... tt: .ascid "TT" ; descriptor for TT nldsc: .ascid "NLA0:" ; descriptor for null device imgdsc: .ascid "SYS$SYSTEM:LOGINOUT.EXE" ; image to run nover: .ascii "$SET NOVERIFY" ; tell loginout not to mumble at user noverl=.-nover assfmt1: .ascid "$ASSIGN !AS TT" ; format string for assign cmd assfmt2: .ascid "$ASSIGN !AS SYS$COMMAND" cmdfmt: .ascid "$@ST_BIN:DODCL/OUT=!AS !AS" ; command format string quotas: .byte pql$_astlm .long 10 .byte pql$_biolm .long 6 .byte pql$_bytlm .long 8192 .byte pql$_cpulm .long 0 .byte pql$_diolm .long 6 .byte pql$_fillm .long 15 .byte pql$_pgflquota .long 1024 .byte pql$_prclm .long 2 .byte pql$_tqelm .long 8 .byte pql$_wsdefault .long 300 .byte pql$_wsquota .long 750 .byte pql$_listend .page .sbttl code ; ; code ; system:: .word ^m ; register save mask tstw trmchn ; initialized yet? beql 1$ ; NO brw 10$ ; continue 1$: $getjpi_s itmlst=jpilst ; fetch pid, base_prio and priv_mask blbs r0,2$ ; lbs => success brw 5$ ; error 2$: movl #8,dumdsc ; prepare descriptor for fao movab pidbuf,dumdsc+4 ; ... $fao_s ctrstr=pidfmt,outbuf=dumdsc,p1=pid ; format pid blbs r0,3$ ; lbs => success brw 5$ ; error 3$: movc3 #8,pidbuf,trmpid ; copy into name strings movc3 #8,pidbuf,argpid ; ... movc3 #8,pidbuf,prcpid ; ... $crembx_s ,trmchn,#100,,#0,,trmdsc ; create termination mailbox blbs r0,6$ ; lbs => success brw 5$ ; error 6$: movl #512,dumdsc ; prepare descriptor for getchn movab buf,dumdsc+4 ; ... $getchn_s trmchn,,dumdsc ; get channel information blbc r0,4$ ; lbc => error movw buf+dib$w_unit,trmunt ; save unit number $trnlog_s tt,length,ttydsc ; translate TT movw length,ttydsc ; copy length into descriptor cmpb #^x1b,ttybuf ; process permanent file? bneq 12$ ; NO addl2 #4,ttydsc+4 ; revise descriptor for tty subl2 #4,ttydsc ; ... 12$: $getdev_s ttydsc,,dumdsc ; get device information blbc r0,11$ ; lbc => error, use nla0: bbs #dev$v_trm,buf+dib$l_devchar,10$ ; if term, OK 11$: movq nldsc,ttydsc ; redefine tty to be null device brb 10$ ; continue to hard stuff 4$: $dassgn_s trmchn ; deassign channel 5$: clrw trmchn ; initialization not complete clrl r0 ; return(0) ret 10$: clrl r0 ; initialize length of buffer movl buffer(ap),r1 ; starting address 20$: tstb (r1)+ ; null character yet? beql 30$ ; YES incl r0 ; increment length brb 20$ ; try again 30$: movl r0,cmddsc ; fill in command descriptor bneq 40$ ; we have something to do brw return_1 ; null command => immediate success 40$: movl buffer(ap),cmddsc+4 ; complete command descriptor $crembx_s ,argchn,#512,,#0,,argdsc ; create argument mailbox blbs r0,50$ ; lbs => success brw return_0 ; error 50$: $creprc_s ,imgdsc,argdsc,nldsc,nldsc,authpr,quotas,prcdsc,prib,,trmunt blbs r0,60$ ; lbs => success $dassgn_s argchn ; deassign the channel brw return_0 ; error 60$: $output argchn,#noverl,nover ; $ set noverify movl #512,dumdsc ; initialize dummy descriptor movab buf,dumdsc+4 ; ... $fao_s assfmt1,length,dumdsc,#ttydsc ; format string $output argchn,length,buf ; $assign 'term' TT $fao_s assfmt2,length,dumdsc,#ttydsc ; format string $output argchn,length,buf ; $assign 'term' SYS$COMMAND $fao_s cmdfmt,length,dumdsc,#ttydsc,#cmddsc ; format string $output argchn,length,buf ; $@dodcl/out='term' 'command' $qiow_s ,argchn,#io$_writeof ; write EOF on mbox $dassgn_s argchn ; deassign channel $input trmchn,#acc$k_termlen,trmsts ; read return message movl trmsts+acc$l_finalsts,r1; fetch return status beql return_1 ; OK if status == 0 blbs r1,return_1 ; OK if low bit set return_0: clrl r0 ; return(0) ret return_1: movl #1,r0 ; return(1) ret .end #-h- st.com 271 asc 29-jul-82 09:51:24 tools (lblh csam sventek) $ tryusr: $ file := st_usr:'p1'.exe $ open/read/error=trybin dcl_file 'file' $ close dcl_file $ goto doit $ trybin: $ file := st_bin:'p1'.exe $ doit: $ np1 := $'file' $ deassign sys$input $ assign/user 'f$logical("TT")' sys$input $ np1 'p2' 'p3' 'p4' 'p5' 'p6' 'p7' 'p8' #-h- uucptomsg.r 5059 asc 09-jan-83 16:36:10 sventek (joseph sventek) #-h- defns 16 asc 18-apr-82 07:10:52 v1.1 (sw-tools v1.1) include mailsym #-h- main 738 asc 22-oct-82 17:45:39 sventek (joseph sventek) subroutine main character addr(MAX_TOK), file(FILENAMESIZE) filedes int, fopen integer getarg, valadr, remove, assign integer junk string usestr "usage: uucptomsg address file" string pname "uucptomsg?" string logfil "~msg/uucptomsg.log" call minit(pname) junk = assign(logfil, ERROUT, APPEND) if (getarg(1, addr, MAX_TOK) == EOF) call remark(usestr) else if (getarg(2, file, FILENAMESIZE) == EOF) call remark(usestr) else if (valadr(addr) == NO) call remark("Attempt to mail to Mailer or Delivr.") else { if (fopen(file, READ, int) == ERR) { call putlin(file, ERROUT) call remark(" - cannot open.") } else { call sendit(addr, int) call close(int) junk = remove(file) } } return end #-h- sendit 3037 asc 07-jan-83 16:52:42 tools (lblh csam sventek) subroutine sendit(addr, int) character addr(ARB), file(FILENAMESIZE), buf(MAXLINE), from(MAX_TOK), host(HOST_SIZE), temp(MAX_TOK), date(10), time(10) integer day, fnddat, fndfrm, i, junk, then(7) integer adrpth, ctoi, getlin, getwrd, length, match1, note, remove, sndmlr, wkday, strmon, savmsg filedes int, out filedes fcreat linepointer lptr string seed "u2m" string datast DATA_STR string datest "Date: " string fromst "From: " string mailst MAIL_FROM_STR string rcptst RCPT_TO_STR string filmsg "Cannot create temp file: " string empmsg "Input file is empty!" string savfil "~msg/dead.u2m" call scratf(seed, file) if (fcreat(file, WRITE, out) == ERR) { return } if (getlin(buf, int) == EOF) { call remark(empmsg) call close(out) } else { i = 1 junk = getwrd(buf, i, from) # From junk = getwrd(buf, i, temp) # username call pthadr(temp, from) # have in user[@host]* format junk = getwrd(buf, i, temp) # skip day of week junk = getwrd(buf, i, temp) # fetch month string then(2) = strmon(temp) # convert to integer then(3) = ctoi(buf, i) # day of month then(4) = ctoi(buf, i) # hour of day i = i + 1 # skip colon then(5) = ctoi(buf, i) # minute of hour i = i + 1 # skip colon then(6) = ctoi(buf, i) # second of minute then(1) = ctoi(buf, i) # year if (then(1) < 100) then(1) = then(1) + 1900 # make a real year if truncated junk = getwrd(buf, i, temp) # remote junk = getwrd(buf, i, temp) # from junk = getwrd(buf, i, host) # have host string if (host(1) != EOS) { i = length(from) + 1 call chcopy('@@', from, i) call stcopy(host, 1, from, i) } junk = adrpth(from, temp) call angbrk(mailst, temp, out) for (i=1; addr(i) != EOS; i=i+1) if (addr(i) == '#' | addr(i) == '.') addr(i) = '@@' junk = adrpth(addr, temp) call angbrk(rcptst, temp, out) call putlnl(datast, out) junk = note(lptr, int) fnddat = NO fndfrm = NO while (getlin(buf, int) != EOF) if (buf(1) == '@n') break else { if (fnddat == NO) andif (match1(buf, datest) == YES) fnddat = YES if (fndfrm == NO) andif (match1(buf, fromst) == YES) fndfrm = YES } call seek(lptr, int) call timstp(host, out) # output time stamp line if (fnddat == NO) # must supply a Date: string { call fmtdat(date, time, then, LETTER) for (i=1; date(i) != EOS; i=i+1) if (date(i) == '-') date(i) = ' ' day = wkday(then(2), then(3), then(1)) call daystr(day, temp) call putlin(datest, out) call putlin(temp, out) call putch(',', out) call putch(' ', out) call putlin(date, out) call putch(' ', out) call putlnl(time, out) } if (fndfrm == NO) # must supply a From: string { junk = adrpth(from, temp) call angbrk(fromst, temp, out) } call fcopy(int, out) call close(out) if (sndmlr(file) == ERR) junk = savmsg(file, savfil) # save file for mretry } junk = remove(file) return end #-h- timstp 667 asc 11-oct-82 07:14:26 sventek (joseph sventek) subroutine timstp(fhost, fd) character fhost(ARB), host(HOST_SIZE), date(10), time(10), zone(4) filedes fd integer i, now(7) string head "Received: from " string middle " by " string tail " with UUCP ; " string uucp "uucp" call putlin(head, fd) call putlin(fhost, fd) call gthost(uucp, host) call scopy(host, 2, host, 1) call putlin(middle, fd) call putlin(host, fd) call putlin(tail, fd) call getnow(now) call gtzone(zone) call fmtdat(date, time, now, LETTER) for (i = 1; date(i) != EOS; i = i + 1) if (date(i) == '-') date(i) = ' ' call putlin(date, fd) call putch(' ', fd) call putlin(time, fd) call putch(' ', fd) call putlnl(zone, fd) return end #-h- valadr 223 asc 18-apr-82 07:10:59 v1.1 (sw-tools v1.1) integer function valadr(addr) character addr(ARB) integer match1 string mailer "Mailer" string delivr "Delivr" if (match1(addr, mailer) == YES) return(NO) if (match1(addr, delivr) == YES) return(NO) return(YES) end #-h- uucpbuild.com 238 asc 29-jul-82 10:00:22 tools (lblh csam sventek) $ set verify $ cc:==$bin:cc.exe cc $ rc:==$st_bin:rc.exe $ cc -c bdsh.c $ cc -c rmail.c $ macro/nolist system $ link bdsh.o,lib:libc.olb/libr $ link rmail.o,system.obj,lib:libc.olb/libr $ rc -v msgtouucp.r -lmsg $ rc -v uucptomsg.r -lmsg #-h- uucphelp.txt 3572 asc 29-jul-82 10:03:13 tools (lblh csam sventek) The following must be performed to provide the UUCP gateway software for the Software Tools Mail System on VMS: 0. The following logical names are assumed to exist during the build and when the images are executing A. Eunice logical names i. bin <--> /bin ii. usr <--> /usr iii. tmp <--> /tmp iv. lib <--> /lib B. Software Tools logical names i. st_bin <--> ~bin ii. st_usr <--> ~usr iii. st_tmp <--> ~tmp iv. st_msg <--> ~msg 1. Invoke @uucpbuild from DCL, which will build the two C programs, bdsh and rmail, together with the Ratfor programs msgtouucp and uucptomsg. It is assumed that the library msg.olb, which was generated when building the baseline Software Tools Mail System is located in the current directory. 2. Any existing rmail.exe images in the normal Eunice search path must be renamed to something else. In addition, a copy of one of the images so renamed must be placed in usr:rmail.exe. 3. The images bdsh.exe and rmail.exe should be placed in /usr/bin. As such, they will be in the normal Eunice search path. 4. The file st.com must be placed in ~usr, along with the images msgtouucp.exe and uucptomsg.exe. It is also necessary to assure that the file st_bin:dodcl.com exists, as `rmail' will end up invoking that to fire up `uucptomsg'. Since it needs to be there for the successful workings of the Software Tools shell, the file should be there. 5. A copy of the Eunice command file unixshell.com must appear in bin:. 6. Now edit the file ~msg/hosts to reflect those adjacent hosts which must be reached via UUCP mail. A typical line would look as follows: lbl-unix lbl-unix |"msgtouucp lbl-unix ??~msg/msgtouucp.log" 7. The forms of address required to reach users on different sides of the UUCP link are as follows: +-----+ +-----+ +-----+ +-----+ |Host0| DECNET |Host1| UUCP |Host2| UUCP |Host3| | |<------>| |<---->| |<---->| | | VMS | | VMS | | UNIX| | ? | +-----+ +-----+ +-----+ +-----+ A. On Host0, valid addresses to `sndmsg' are User@Host1, <@Host1,User@Host2>, <@Host1,Host3!User@Host2> B. On Host1, valid addresses to `sndmsg' are User@Host0, User@Host2, Host3!User@Host2 C. On Host2, valid addresses to `mail' are Host1!User#Host0, Host1!User, Host3!User D. On Host0 and Host1, the rewriting rules embodied in ~msg/hnames and ~/hnames may be used to simplify addresses of users more than one hop away. If the following entries appear in ~msg/hnames or ~/hnames Host0: @Host2 &@Host2@Host1 @Host3 Host3!&@Host2@Host1 Host1: @Host3 Host3!&@Host2 then the address User@Host3 will be rewritten as Host3!User@Host2 on Host1 and the address User@Host3 will be rewritten as Host3!User@Host2@Host! on Host0 before delivery is attempted. Thus users several hops away can be addressed identically to users on adjacent machines. 8. Users on the UNIX machines should be cautioned NOT to use the lower-case reply command in Big Mail, since the UNIX delivery system mungs the address lists in the message headers, with the result that r[eply] will try to address all sorts of invalid addresses, while R[eply] will only reply to whoever sent the message, which will be valid. The answer command in `msg' on the VMS systems acts like the R[eply] command, and has no problems. #-h- umtptx.r 4370 asc 22-dec-82 22:26:54 tools (lblh csam sventek) #-h- defns 16 asc 01-nov-82 08:46:25 sventek (joseph sventek) include mailsym #-h- muckup 137 asc 04-nov-82 16:02:17 sventek (joseph sventek) subroutine muckup(buf) character buf(ARB) integer i for (i=1; buf(i) != EOS; i=i+1) if (buf(i) == '@@') buf(i) = '.' return end #-h- put1st 678 asc 01-nov-82 08:46:29 sventek (joseph sventek) subroutine put1st(name, then, host, out) filedes out character name(ARB), host(ARB), temp(20), time(10) integer day, wkday, then(7) string from "From " string remote " remote from " call putlin(from, out) call putlin(name, out) call putch(' ', out) day = wkday(then(2), then(3), then(1)) call daystr(day, temp) temp(4) = EOS call putlin(temp, out) call putch(' ', out) call monstr(then(2), temp) temp(4) = EOS call putlin(temp, out) call putch(' ', out) call putint(then(3), 1, out) call putch(' ', out) call fmtdat(temp, time, then, LETTER) call putlin(time, out) call putch(' ', out) call putint(then(1), 1, out) call putlin(remote, out) call putlnl(host, out) return end #-h- umtptx 3230 asc 08-dec-82 00:57:37 tools (lblh csam sventek) integer function umtptx(host, buf, file) filedes out, in filedes fcreat, open, fopen integer i, junk, status, now(7) integer getlin, match1, length, spawn, equal, remove, rindex character buf(MAXLINE), token(MAX_TOK), sender(MAX_TOK), host(HOST_SIZE), pid(PIDSIZE), myhost(HOST_SIZE) string adrfil "~tmp/umtptx.adr" ifdef(RSX) string uuxfil "~tmp/umtptx.uux" string shxfil "~tmp/umtptx.shx" elsedef string uuxfil "tmp:umtptx.uux" string shxfil "tmp:umtptx.shx" enddef string cmd0 "uux - " string cmd1 "!rmail (" string cmd2 ")