$! ------------------ CUT HERE ----------------------- $ v='f$verify(f$trnlnm("SHARE_VERIFY"))' $! $! This archive created by VMS_SHARE Version 7.2-007 22-FEB-1990 $! On 3-OCT-1990 09:44:17.16 By user TP $! $! This VMS_SHARE Written by: $! Andy Harper, Kings College London UK $! $! Acknowledgements to: $! James Gray - Original VMS_SHARE $! Michael Bednarek - Original Concept and implementation $! $! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER $! AND EXECUTE AS A COMMAND PROCEDURE ( @name ) $! $! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING: $! 1. ARGPROC.C;12 $! 2. CRTL.OPT;1 $! 3. DESCRIP.MMS;2 $! 4. UUCAT.C;6 $! 5. UUDECODE.C;4 $! 6. UUENCODE.C;3 $! 7. VMSBUILD.COM;2 $! $set="set" $set symbol/scope=(nolocal,noglobal) $f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID")) $e="write sys$error ""%UNPACK"", " $w="write sys$output ""%UNPACK"", " $ if f$trnlnm("SHARE_LOG") then $ w = "!" $ ve=f$getsyi("version") $ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START $ e "-E-OLDVER, Must run at least VMS 4.4" $ v=f$verify(v) $ exit 44 $UNPACK: SUBROUTINE ! P1=filename, P2=checksum $ if f$search(P1) .eqs. "" then $ goto file_absent $ e "-W-EXISTS, File ''P1' exists. Skipped." $ delete 'f'* $ exit $file_absent: $ if f$parse(P1) .nes. "" then $ goto dirok $ dn=f$parse(P1,,,"DIRECTORY") $ w "-I-CREDIR, Creating directory ''dn'." $ create/dir 'dn' $ if $status then $ goto dirok $ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped." $ delete 'f'* $ exit $dirok: $ w "-I-PROCESS, Processing file ''P1'." $ if .not. f$verify() then $ define/user sys$output nl: $ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1' PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET( SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:= CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b)); LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION( BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1); IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE; MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1; ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")= 1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF"; POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r); ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1; COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE, "output_file"));ENDPROCEDURE;Unpacker;QUIT; $ delete/nolog 'f'* $ CHECKSUM 'P1' $ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT $ e "-E-CHKSMFAIL, Checksum of ''P1' failed." $ ENDSUBROUTINE $START: $ create 'f' X/* X * @(#)argproc.c 1.0 89/02/01`09`09Mark Pizzolato (mark@infopiz.uucp)`09 X */ X X#ifndef lint Xchar argproc_version`5B`5D = "@(#)argproc.c VMS uucp Version infopiz-1.0"; X#endif X X/* Include of "includes.h" removed, replaced by the following: */ X X#include ctype X#include descrip X#include dvidef X#include errno X#include iodef X#include setjmp X#include stat X#include stdlib`20 X#include stdio X#include string X `20 X#define EXIT_OK 1`09`09/* image exit code */ X#define EXIT_ERR 0x10000000`09/* image exit code */ X`0C X/* X * getredirection() is intended to aid in porting C programs X * to VMS (Vax-11 C) which does not support '>' and '<' X * I/O redirection, along with a command line pipe mechanism X * using the '`7C' AND background command execution '&'. X * The piping mechanism will probably work with almost any 'filter' type X * of program. With suitable modification, it may useful for other X * portability problems as well. X * X * Author: Mark Pizzolato`09mark@infopiz.UUCP X */ Xstruct list_item X `7B X struct list_item *next; X char *value; X `7D; X Xint Xgetredirection(ac, av) Xint`09`09*ac; Xchar`09`09***av; X/* X * Process vms redirection arg's. Exit if any error is seen. X * If getredirection() processes an argument, it is erased X * from the vector. getredirection() returns a new argc and argv value. X * In the event that a background command is requested (by a trailing "&"), X * this routine creates a background subprocess, and simply exits the progra Vm. X * X * Warning: do not try to simplify the code for vms. The code X * presupposes that getredirection() is called before any data is X * read from stdin or written to stdout. X * X * Normal usage is as follows: X * X *`09main(argc, argv) X *`09int`09`09argc; X * `09char`09`09*argv`5B`5D; X *`09`7B X *`09`09getredirection(&argc, &argv); X *`09`7D X */ X`7B X int`09`09`09argc = *ac;`09/* Argument Count`09 */ X char`09`09**argv = *av;`09/* Argument Vector`09 */ X char`09`09*ap; `09`09/* Argument pointer`09 */ X int`09 `09`09j;`09`09/* argv`5B`5D index`09`09 */ X extern int`09`09errno;`09`09/* Last vms i/o error `09 */ X int`09`09`09item_count = 0;`09/* Count of Items in List */ X struct list_item `09*list_head = 0;`09/* First Item in List`09 */ X struct list_item`09*list_tail;`09/* Last Item in List`09 */ X char `09`09*in = NULL;`09/* Input File Name`09 */ X char `09`09*out = NULL;`09/* Output File Name`09 */ X char `09`09*outmode = "w";`09/* Mode to Open Output File */ X int`09`09`09cmargc = 0; `09/* Piped Command Arg Count */ X char`09`09**cmargv = NULL;/* Piped Command Arg Vector */ X stat_t`09`09statbuf;`09/* fstat buffer`09`09 */ X X /* X * First handle the case where the last thing on the line ends with X * a '&'. This indicates the desire for the command to be run in a X * subprocess, so we satisfy that desire. X */ X ap = argv`5Bargc-1`5D; X if (0 == strcmp("&", ap)) X`09exit(background_process(--argc, argv)); X if ('&' == ap`5Bstrlen(ap)-1`5D) X`09`7B X`09ap`5Bstrlen(ap)-1`5D = '\0'; X`09exit(background_process(argc, argv)); X`09`7D X /* X * Now we handle the general redirection cases that involve '>', '>>', X * '<', and pipes '`7C'. X */ X for (j = 0; j < argc; ++j) X`09`7B X`09if (0 == strcmp("<", argv`5Bj`5D)) X`09 `7B X`09 if (j+1 >= argc) X`09`09`7B X`09`09errno = EINVAL; X`09`09perror("No input file"); X`09`09exit(EXIT_ERR); X`09`09`7D X`09 in = argv`5B++j`5D; X`09 continue; X`09 `7D X`09if ('<' == *(ap = argv`5Bj`5D)) X`09 `7B X`09 in = 1 + ap; X`09 continue; X`09 `7D X`09if (0 == strcmp(">", ap)) X`09 `7B X`09 if (j+1 >= argc) X`09`09`7B X`09`09errno = EINVAL; X`09`09perror("No output file"); X`09`09exit(EXIT_ERR); X`09`09`7D X`09 out = argv`5B++j`5D; X`09 continue; X`09 `7D X`09if ('>' == *ap) X`09 `7B X`09 if ('>' == ap`5B1`5D) X`09`09`7B X`09`09outmode = "a"; X`09`09if ('\0' == ap`5B2`5D) X`09`09 out = argv`5B++j`5D; X`09`09else X`09`09 out = 2 + ap; X`09`09`7D X`09 else X`09`09out = 1 + ap; X`09 continue; X`09 `7D X`09if (0 == strcmp("`7C", argv`5Bj`5D)) X`09 `7B X`09 if (j+1 >= argc) X`09`09`7B X`09`09errno = EPIPE; X`09`09perror("No command to Pipe to"); X`09`09exit(EXIT_ERR); X`09`09`7D X`09 cmargc = argc-(j+1); X`09 cmargv = &argv`5Bj+1`5D; X`09 argc = j; X`09 continue; X`09 `7D X`09if ('`7C' == *(ap = argv`5Bj`5D)) X`09 `7B X`09 ++argv`5Bj`5D; X`09 cmargc = argc-j; X`09 cmargv = &argv`5Bj`5D; X`09 argc = j; X`09 continue; X`09 `7D X`09expand_wild_cards(ap, &list_head, &list_tail, &item_count); X`09`7D X /* X * Allocate and fill in the new argument vector, Some Unix's terminate X * the list with an extra null pointer. X */ X argv = *av = calloc(item_count+1, sizeof(char *)); X for (j = 0; j < item_count; ++j, list_head = list_head->next) X`09argv`5Bj`5D = list_head->value; X *ac = item_count; X if (cmargv != NULL) X`09`7B X`09char subcmd`5B1024`5D; X`09static char *pipe_and_fork(); X X`09if (out != NULL) X`09 `7B X`09 errno = EINVAL; X`09 perror("Invalid '`7C' and '>' specified"); X`09 exit(EXIT_ERR); X`09 `7D X`09strcpy(subcmd, cmargv`5B0`5D); X`09for (j = 1; j < cmargc; ++j) X`09 `7B X`09 strcat(subcmd, " \""); X`09 strcat(subcmd, cmargv`5Bj`5D); X`09 strcat(subcmd, "\""); X`09 `7D X`09out = pipe_and_fork(subcmd); X`09outmode = "wb"; X`09`7D X`09 X /* Check for input from a pipe (mailbox) */ X X if(fstat(0, &statbuf) == 0)`7B X`09if(strncmp(statbuf.st_dev, "MB", 2) == 0 `7C`7C`20 X`09 strncmp(statbuf.st_dev, "_MB", 3) == 0)`7B X X`09 /* Input from a pipe, reopen it in binary mode to disable`09*/ X`09 /* carriage control processing.`09`09`09`09*/ X X`09 if (in != NULL)`7B X`09`09errno = EINVAL; X`09`09perror("Invalid '`7C' and '<' specified"); X`09`09exit(EXIT_ERR); X`09`09`7D X`09 freopen(statbuf.st_dev, "rb", stdin); X`09 `7D X`09`7D X else `7B X`09perror("fstat failed"); X`09exit(EXIT_ERR); X`09`7D X if ((in != NULL) && (NULL == freopen(in, "r", stdin, "mbc=32", "mbf=2")) V) X`09`7B X`09perror(in); `09 `09/* Can't find file`09`09*/ X`09exit(EXIT_ERR);`09`09/* Is a fatal error`09`09*/ X`09`7D X if ((out != NULL) && (NULL == freopen(out, outmode, stdout, "mbc=32", "m Vbf=2"))) X`09`7B`09 X`09perror(ap);`09`09/* Error, can't write or append`09*/ X`09exit(EXIT_ERR);`09`09/* Is a fatal error`09`09*/ X`09`7D X#ifdef DEBUG X fprintf(stderr, "Arglist:\n"); X for (j = 0; j < *ac; ++j) X`09fprintf(stderr, "argv`5B%d`5D = '%s'\n", j, argv`5Bj`5D); X#endif X`7D X Xstatic add_item(head, tail, value, count) Xstruct list_item **head; Xstruct list_item **tail; Xchar *value; Xint *count; X`7B X if (*head == 0) X`09`7B X`09if (NULL == (*head = calloc(1, sizeof(**head)))) X`09 `7B X`09 errno = ENOMEM; X`09 perror(""); X`09 exit(EXIT_ERR); X`09 `7D X`09*tail = *head; X`09`7D X else X`09if (NULL == ((*tail)->next = calloc(1, sizeof(**head)))) X`09 `7B X`09 errno = ENOMEM; X`09 perror(""); X`09 exit(EXIT_ERR); X`09 `7D X`09else X`09 *tail = (*tail)->next; X (*tail)->value = value; X ++(*count); X`7D X Xstatic expand_wild_cards(item, head, tail, count) Xchar *item; Xstruct ltem_list **head; Xstruct ltem_list **tail; Xint *count; X`7B Xint expcount = 0; Xint context = 0; Xint status; Xint status_value; Xint had_version; X$DESCRIPTOR(filespec, item); X$DESCRIPTOR(defaultspec, "SYS$DISK:`5B`5D*.*;"); X$DESCRIPTOR(resultspec, ""); X X if (strcspn(item, "*%") == strlen(item)) X`09`7B X`09add_item(head, tail, item, count); X`09return; X`09`7D X resultspec.dsc$b_dtype = DSC$K_DTYPE_T; X resultspec.dsc$b_class = DSC$K_CLASS_D; X resultspec.dsc$a_pointer = NULL; X filespec.dsc$w_length = strlen(item); X /* X * Only return version specs, if the caller specified a version X */ X had_version = strchr(item, ';'); X while (1 == (1&lib$find_file(&filespec, &resultspec, &context, X `09`09`09`09 &defaultspec, 0, &status_value, &0))) X`09`7B X`09char *string; X`09char *c; X X`09if (NULL == (string = calloc(1, resultspec.dsc$w_length+1))) X`09 `7B X`09 errno = ENOMEM; X`09 perror(""); X`09 exit(EXIT_ERR); X`09 `7D X`09strncpy(string, resultspec.dsc$a_pointer, resultspec.dsc$w_length); X`09string`5Bresultspec.dsc$w_length`5D = '\0'; X`09if (NULL == had_version) X`09 *((char *)strrchr(string, ';')) = '\0'; X`09/* X`09 * Be consistent with what the C RTL has already done to the rest of X`09 * the argv items and lowercase all of these names. X`09 */ X`09for (c = string; *c; ++c) X`09 if (isupper(*c)) X`09`09*c = tolower(*c); X`09add_item(head, tail, string, count); X`09++expcount; X`09`7D X if (expcount == 0) X`09add_item(head, tail, item, count); X lib$sfree1_dd(&resultspec); X lib$find_file_end(&context); X`7D X Xstatic int child_st`5B2`5D;`09/* Event Flag set when child process completes V`09*/ X Xstatic short child_chan;/* I/O Channel for Pipe Mailbox`09`09`09*/ X Xstatic exit_handler(status) Xint *status; X`7B Xshort iosb`5B4`5D; X X if (0 == child_st`5B0`5D) X`09`7B X#ifdef DEBUG X`09fprintf(stderr, "Waiting for Child Process to Finish . . .\n"); X#endif X`09fflush(stdout);`09 /* Have to flush pipe for binary data to`09*/ X`09`09`09 /* terminate properly -- `09*/ X`09sys$qiow(0, child_chan, IO$_WRITEOF, iosb, 0, 0, 0, 0, 0, 0, 0, 0); X`09sys$dassgn(child_chan); X`09fclose(stdout); X`09sys$purgws(0); X`09sys$synch(0, child_st); X`09`7D X`7D X X#include syidef`09`09/* System Information Definitions`09*/ X Xstatic sig_child(chan) Xint chan; X`7B X#ifdef DEBUG X fprintf(stderr, "Child Completion AST\n"); X#endif X if (child_st`5B0`5D == 0) X`09child_st`5B0`5D = 1; X`7D X Xstatic struct exit_control_block X `7B X struct exit_control_block *flink; X int`09(*exit_routine)(); X int arg_count; X int *status_address; X int exit_status; X `7D exit_block = X `7B X 0, X exit_handler, X 1, X &exit_block.exit_status, X 0 X `7D; X Xstatic char *pipe_and_fork(cmd) Xchar *cmd; X`7B X $DESCRIPTOR(cmddsc, cmd); X static char mbxname`5B64`5D; X $DESCRIPTOR(mbxdsc, mbxname); X short iosb`5B4`5D; X int status; X int pid; X struct X`09`7B X`09short dna_buflen; X`09short dna_itmcod; X`09char *dna_buffer; X`09short *dna_retlen; X`09int listend; X`09`7D itmlst = X`09`7B X`09sizeof(mbxname), X`09DVI$_DEVNAM, X`09mbxname, X`09&mbxdsc.dsc$w_length, X`090 X`09`7D; X int mbxsize; X struct X`09`7B X`09short mbf_buflen; X`09short mbf_itmcod; X`09int *mbf_maxbuf; X`09short *mbf_retlen; X`09int listend; X`09`7D syiitmlst = X`09`7B X`09sizeof(mbxsize), X`09SYI$_MAXBUF, X`09&mbxsize, X`090, X`090 X`09`7D; X X cmddsc.dsc$w_length = strlen(cmd); X /* X * Get the SYSGEN parameter MAXBUF, and the smaller of it and 2048 as X * the size of the 'pipe' mailbox. X */ X if (1 == (1&(vaxc$errno = sys$getsyiw(0, 0, 0, &syiitmlst, iosb, 0, 0, 0 V)))) X`09vaxc$errno = iosb`5B0`5D; X if (0 == (1&vaxc$errno)) X`09`7B X `09errno = EVMSERR; X`09perror("Can't get SYSGEN parameter value for MAXBUF"); X`09exit(EXIT_ERR); X`09`7D X if (mbxsize > 2048) X`09mbxsize = 2048; X if (0 == (1&(vaxc$errno = sys$crembx(0, &child_chan, mbxsize, mbxsize, 0 V, 0, 0)))) X`09`7B X`09errno = EVMSERR; X`09perror("Can't create pipe mailbox"); X`09exit(EXIT_ERR); X`09`7D X if (1 == (1&(vaxc$errno = sys$getdviw(0, child_chan, 0, &itmlst, iosb, X `09`09`09`09`09 0, 0, 0)))) X`09vaxc$errno = iosb`5B0`5D; X if (0 == (1&vaxc$errno)) X`09`7B X `09errno = EVMSERR; X`09perror("Can't get pipe mailbox device name"); X`09exit(EXIT_ERR); X`09`7D X mbxname`5Bmbxdsc.dsc$w_length`5D = '\0'; X#ifdef DEBUG X fprintf(stderr, "Pipe Mailbox Name = '%s'\n", mbxname); X#endif X if (0 == (1&(vaxc$errno = lib$spawn(&cmddsc, &mbxdsc, 0, &1, X `09`09`09`09`090, &pid, child_st, &0, sig_child, X `09`09`09`09`09&child_chan)))) X`09`7B X`09errno = EVMSERR; X`09perror("Can't spawn subprocess"); X`09exit(EXIT_ERR); X`09`7D X#ifdef DEBUG X fprintf(stderr, "Subprocess's Pid = %08X\n", pid); X#endif X sys$dclexh(&exit_block); X return(mbxname); X`7D X Xbackground_process(argc, argv) Xint argc; Xchar **argv; X`7B Xchar command`5B2048`5D = "$"; X$DESCRIPTOR(value, command); X$DESCRIPTOR(cmd, "BACKGROUND$COMMAND"); X$DESCRIPTOR(null, "NLA0:"); Xint pid; X X strcat(command, argv`5B0`5D); X while (--argc) X`09`7B X`09strcat(command, " \""); X`09strcat(command, *(++argv)); X`09strcat(command, "\""); X`09`7D X value.dsc$w_length = strlen(command); X if (0 == (1&(vaxc$errno = lib$set_symbol(&cmd, &value)))) X`09`7B X`09errno = EVMSERR; X`09perror("Can't create symbol for subprocess command"); X`09exit(EXIT_ERR); X`09`7D X if (0 == (1&(vaxc$errno = lib$spawn(&cmd, &null, 0, &17, 0, &pid)))) X`09`7B X`09errno = EVMSERR; X`09perror("Can't spawn subprocess"); X`09exit(EXIT_ERR); X`09`7D X#ifdef DEBUG X fprintf(stderr, "%s\n", command); X#endif X fprintf(stderr, "%08X\n", pid); X return(EXIT_OK); X`7D X`0C X/* got this off net.sources */ X X#ifdef`09VMS X#define`09index`09strchr X#endif`09/*VMS*/ X X/* X * get option letter from argument vector X */ Xint`09opterr = 1,`09`09/* useless, never set or used */ X`09optind = 1,`09`09/* index into parent argv vector */ X`09optopt;`09`09`09/* character checked for validity */ Xchar`09*optarg;`09`09/* argument associated with option */ X X#define BADCH`09(int)'?' X#define EMSG`09"" X#define tell(s)`09fputs(*nargv,stderr);fputs(s,stderr); \ X`09`09fputc(optopt,stderr);fputc('\n',stderr);return(BADCH); X Xgetopt(nargc,nargv,ostr) Xint`09nargc; Xchar`09**nargv, X`09*ostr; X`7B X`09static char`09*place = EMSG;`09/* option letter processing */ X`09register char`09*oli;`09`09/* option letter list index */ X`09char`09*index(); X X`09if(!*place) `7B`09`09`09/* update scanning pointer */ X`09`09if(optind >= nargc `7C`7C *(place = nargv`5Boptind`5D) != '-' `7C`7C ! V*++place) return(EOF); X`09`09if (*place == '-') `7B`09/* found "--" */ X`09`09`09++optind; X`09`09`09return(EOF); X`09`09`7D X`09`7D`09`09`09`09/* option letter okay? */ X`09if ((optopt = (int)*place++) == (int)':' `7C`7C !(oli = index(ostr,optopt V))) `7B X`09`09if(!*place) ++optind; X`09`09tell(": illegal option -- "); X`09`7D X`09if (*++oli != ':') `7B`09`09/* don't need argument */ X`09`09optarg = NULL; X`09`09if (!*place) ++optind; X`09`7D X`09else `7B`09`09`09`09/* need an argument */ X`09`09if (*place) optarg = place;`09/* no white space */ X`09`09else if (nargc <= ++optind) `7B`09/* no arg */ X`09`09`09place = EMSG; X`09`09`09tell(": option requires an argument -- "); X`09`09`7D X`09 `09else optarg = nargv`5Boptind`5D;`09/* white space */ X`09`09place = EMSG; X`09`09++optind; X`09`7D X`09return(optopt);`09`09`09/* dump back option letter */ X`7D $ CALL UNPACK ARGPROC.C;12 1661485956 $ create 'f' Xsys$share:vaxcrtl.exe/share $ CALL UNPACK CRTL.OPT;1 1392527948 $ create 'f' X.first X`09def sys sys$library X Xall : uuencode.exe uudecode.exe uucat.exe X`09! Done. X Xuuencode.exe : uuencode.obj argproc.obj X`09$(link) $(linkflags) uuencode.obj,argproc.obj,crtl.opt/opt X Xuudecode.exe : uudecode.obj argproc.obj X`09$(link) $(linkflags) uudecode.obj,argproc.obj,crtl.opt/opt X Xuucat.exe : uucat.obj argproc.obj X`09$(link) $(linkflags) uucat.obj,argproc.obj,crtl.opt/opt X $ CALL UNPACK DESCRIP.MMS;2 538268317 $ create 'f' X/* uucat.c */ X X#include X#include X X#define TRUE`091 X#define FALSE`090 X X#define LENGTH`09150 X Xextern void uuread(); X X X#ifndef VMS Xvoid`20 X#endif Xmain(argc, argv) Xint argc; Xchar *argv`5B`5D; X`7B X int error, argno; X FILE *infile; X X#ifdef VMS X getredirection(&argc, &argv); X#endif X if (argc < 2) X uuread(stdin); X else X `7B X error = FALSE; X for (argno = 1; !error && argno < argc; argno++) X `7B X#ifdef VMS X if ((infile = fopen(argv`5Bargno`5D, "r","mbc=32","mbf=2")) == NULL) X#else X if ((infile = fopen(argv`5Bargno`5D, "r")) == NULL) X#endif X `7B X`09error = TRUE; X`09fprintf(stderr, "uucat: Can't open '%s' for input.\n", argv`5Bargno`5D); X `7D X else X `7B X`09uuread(infile); X`09fclose(infile); X `7D X `7D X `7D X X exit(0); X`7D X X Xvoid uuread(infile) XFILE *infile; X`7B X char *s2, *s1, *s0, *tmp_s; X int length; X static char s`5B3 * (LENGTH + 1)`5D; X static int echo_on = FALSE, started = FALSE, just_finished = FALSE; X static int line_length = 0, lines_to_go = 0; X X s0 = s; X s1 = s0 + (LENGTH + 1); X s2 = s1 + (LENGTH + 1); X X s0`5B0`5D = s1`5B0`5D = s2`5B0`5D = '\0'; /* Clear strings */ X X while (fgets(s0, LENGTH, infile) != NULL) X `7B X s0`5BLENGTH`5D = '\0'; /* Make sure string is terminated */ X X if (just_finished) X `7B X if (strncmp(s0, "size ", 5) == 0) X `7B X`09fputs(s0, stdout); X`09s0`5B0`5D = '\0'; X `7D X just_finished = FALSE; X `7D X X if (!started) X `7B X if (strncmp(s0, "begin ", 6) == 0) X `7B X`09started = echo_on = TRUE; X`09line_length = 0; X`09lines_to_go = 0; X `7D X `7D X else /* started */ X `7B X length = strlen(s0); X if (line_length == 0) X`09line_length = length; X X if (echo_on) X `7B X`09lines_to_go = 0; X`09if (s0`5B0`5D != 'M' `7C`7C length != line_length) X`09`7B X`09 echo_on = FALSE; X`09 lines_to_go = 2; /* Lines to go before 'end' is expected */ X`09 if (s0`5B0`5D == ' ' `7C`7C s0`5B0`5D == '`60') X`09 lines_to_go = 1; X`09`7D X `7D X else /* !echo_on */ X `7B X`09if (s0`5B0`5D == 'M' && length == line_length) X`09 echo_on = TRUE; X`09else if (lines_to_go > 0) X`09`7B X`09 if (lines_to_go == 2) X`09 `7B X`09 if (s0`5B0`5D == ' ' `7C`7C s0`5B0`5D == '`60') X`09 lines_to_go = 1; X`09 else X`09 lines_to_go = 0; /* Unexpected line, so break off */ X`09 `7D X`09 else if (lines_to_go == 1) X`09 `7B X`09 if (strcmp(s0, "end\n") == 0) X`09 `7B X`09 fputs(s2, stdout); X`09 fputs(s1, stdout); X`09 fputs(s0, stdout); X`09 lines_to_go = 0; /* Done. Break off */ X`09 just_finished = TRUE; X`09 started = FALSE; X`09 `7D X`09 else X`09 lines_to_go = 0; /* Unexpected line, so break off */ X`09 `7D X`09`7D X `7D X `7D X X if (echo_on) X `7B X fputs(s0, stdout); X s0`5B0`5D = '\0'; X `7D X X tmp_s = s2; X s2 = s1; X s1 = s0; X s0 = tmp_s; X `7D X`7D $ CALL UNPACK UUCAT.C;6 343351343 $ create 'f' X#ifndef lint Xstatic char sccsid`5B`5D = "@(#)uudecode.c`095.3 (Berkeley) 4/10/85"; X#endif X`20 X/* X * uudecode `5Binput`5D X * X * create the specified file, decoding as you go. X * used with uuencode. X */ X#include X#ifndef VMS X#include X#endif X#include X#include X`20 X/* single character decode */ X#define DEC(c)`09(((c) - ' ') & 077) X`20 Xmain(argc, argv) Xchar **argv; X`7B X`09FILE *in, *out; X`09int mode; X`09char dest`5B128`5D; X`09char buf`5B80`5D; X`20 X#ifdef VMS X`09getredirection(&argc, &argv); X#endif X`09/* optional input arg */ X`09if (argc > 1) `7B X#ifdef VMS X`09`09if ((in = fopen(argv`5B1`5D, "r", "mbc=32", "mbf=2")) == NULL) `7B X#else X`09`09if ((in = fopen(argv`5B1`5D, "r")) == NULL) `7B X#endif X`09`09`09perror(argv`5B1`5D); X`09`09`09exit(1); X`09`09`7D X`09`09argv++; argc--; X`09`7D else X`09`09in = stdin; X`20 X`09if (argc != 1) `7B X`09`09printf("Usage: uudecode `5Binfile`5D\n"); X`09`09exit(2); X`09`7D X`20 X`09/* search for header line */ X`09for (;;) `7B X`09`09if (fgets(buf, sizeof buf, in) == NULL) `7B X`09`09`09fprintf(stderr, "No begin line\n"); X`09`09`09exit(3); X`09`09`7D X`09`09if (strncmp(buf, "begin ", 6) == 0) X`09`09`09break; X`09`7D X`09sscanf(buf, "begin %o %s", &mode, dest); X`20 X`09/* handle `7Euser/file format */ X`09if (dest`5B0`5D == '`7E') `7B X#ifdef VMS X X`09`09/* Under VMS just strip it off */ X X`09`09char *sl; X`09`09char dnbuf`5B100`5D; X`20 X`09`09sl = strchr(dest, '/'); X`09`09if (sl == NULL) `7B X`09`09`09fprintf(stderr, "Illegal `7Euser\n"); X`09`09`09exit(3); X`09`09`7D X`09`09strcat(dnbuf, sl+1); X`09`09strcpy(dest, dnbuf); X#else X`09`09char *sl; X`09`09struct passwd *getpwnam(); X`09`09char *index(); X`09`09struct passwd *user; X`09`09char dnbuf`5B100`5D; X`20 X`09`09sl = index(dest, '/'); X`09`09if (sl == NULL) `7B X`09`09`09fprintf(stderr, "Illegal `7Euser\n"); X`09`09`09exit(3); X`09`09`7D X`09`09*sl++ = 0; X`09`09user = getpwnam(dest+1); X`09`09if (user == NULL) `7B X`09`09`09fprintf(stderr, "No such user as %s\n", dest); X`09`09`09exit(4); X`09`09`7D X`09`09strcpy(dnbuf, user->pw_dir); X`09`09strcat(dnbuf, "/"); X`09`09strcat(dnbuf, sl); X`09`09strcpy(dest, dnbuf); X#endif X`09`7D X`20 X`09/* create output file */ X#ifdef VMS X`09out = fopen(dest, "w", "mbc=32", "mbf=2"); X#else X`09out = fopen(dest, "w"); X#endif X`09if (out == NULL) `7B X`09`09perror(dest); X`09`09exit(4); X`09`7D X`09chmod(dest, mode); X`20 X`09decode(in, out); X`20 X`09if (fgets(buf, sizeof buf, in) == NULL `7C`7C strcmp(buf, "end\n")) `7B X`09`09fprintf(stderr, "No end line\n"); X`09`09exit(5); X`09`7D X`09exit(0); X`7D X`20 X/* X * copy from in to out, decoding as you go along. X */ Xdecode(in, out) XFILE *in; XFILE *out; X`7B X`09char buf`5B80`5D; X`09char *bp; X`09int n; X`20 X`09for (;;) `7B X`09`09/* for each input line */ X`09`09if (fgets(buf, sizeof buf, in) == NULL) `7B X`09`09`09printf("Short file\n"); X`09`09`09exit(10); X`09`09`7D X`09`09n = DEC(buf`5B0`5D); X`09`09if (n <= 0) X`09`09`09break; X`20 X`09`09bp = &buf`5B1`5D; X`09`09while (n > 0) `7B X`09`09`09outdec(bp, out, n); X`09`09`09bp += 4; X`09`09`09n -= 3; X`09`09`7D X`09`7D X`7D X`20 X/* X * output a group of 3 bytes (4 input characters). X * the input chars are pointed to by p, they are to X * be output to file f. n is used to tell us not to X * output all of them at the end of the file. X */ Xoutdec(p, f, n) Xchar *p; XFILE *f; X`7B X`09int c1, c2, c3; X`20 X`09c1 = DEC(*p) << 2 `7C DEC(p`5B1`5D) >> 4; X`09c2 = DEC(p`5B1`5D) << 4 `7C DEC(p`5B2`5D) >> 2; X`09c3 = DEC(p`5B2`5D) << 6 `7C DEC(p`5B3`5D); X`09if (n >= 1) X`09`09putc(c1, f); X`09if (n >= 2) X`09`09putc(c2, f); X`09if (n >= 3) X`09`09putc(c3, f); X`7D X`20 X`20 X/* fr: like read but stdio */ Xint Xfr(fd, buf, cnt) XFILE *fd; Xchar *buf; Xint cnt; X`7B X`09int c, i; X`20 X`09for (i=0; i X#include X#include X`20 X/* ENC is the basic 1 character encoding function to make a char printing */ X#define ENC(c) ((c) ? ((c) & 077) + ' ': '`60') X`20 Xmain(argc, argv) Xchar **argv; X`7B X`09FILE *in; X`09struct stat sbuf; X`09int mode; X`20 X#ifdef VMS X`09getredirection(&argc, &argv); X#endif X`09/* optional 1st argument */ X`09if (argc > 2) `7B X#ifdef VMS X`09`09if ((in = fopen(argv`5B1`5D, "r", "mbc=32", "mbf=2")) == NULL) `7B X#else X`09`09if ((in = fopen(argv`5B1`5D, "r")) == NULL) `7B X#endif X`09`09`09perror(argv`5B1`5D); X`09`09`09exit(1); X`09`09`7D X`09`09argv++; argc--; X`09`7D else X`09`09in = stdin; X`20 X`09if (argc != 2) `7B X`09`09fprintf(stderr,"Usage: uuencode `5Binfile`5D remotefile\n"); X`09`09exit(2); X`09`7D X`20 X`09/* figure out the input file mode */ X`09if (fstat(fileno(in), &sbuf) < 0 `7C`7C !isatty(fileno(in))) X`09`09mode = 0666 & `7Eumask(0666); X`09else X`09`09mode = sbuf.st_mode & 0777; X`09printf("begin %o %s\n", mode, argv`5B1`5D); X`20 X`09encode(in, stdout); X`20 X`09printf("end\n"); X`09exit(0); X`7D X`20 X/* X * copy from in to out, encoding as you go along. X */ Xencode(in, out) Xregister FILE *in; Xregister FILE *out; X`7B X`09char buf`5B80`5D; X`09register int i, n; X`20 X`09for (;;) `7B X`09`09/* 1 (up to) 45 character line */ X`09`09n = fread(buf, 1, 45, in); X`09`09putc(ENC(n), out); X`20 X`09`09for (i=0; i> 2; X`09c2 = (*p << 4) & 060 `7C (p`5B1`5D >> 4) & 017; X`09c3 = (p`5B1`5D << 2) & 074 `7C (p`5B2`5D >> 6) & 03; X`09c4 = p`5B2`5D & 077; X`09putc(ENC(c1), f); X`09putc(ENC(c2), f); X`09putc(ENC(c3), f); X`09putc(ENC(c4), f); X`7D $ CALL UNPACK UUENCODE.C;3 843254265 $ create 'f' X$ def sys sys$library X$ CC /NOLIST/OBJECT=UUENCODE.OBJ UUENCODE.C X$ CC /NOLIST/OBJECT=ARGPROC.OBJ ARGPROC.C X$ LINK /TRACE/NOMAP/EXEC=UUENCODE.EXE uuencode.obj,argproc.obj,crtl.opt/opt X$ CC /NOLIST/OBJECT=UUDECODE.OBJ UUDECODE.C X$ LINK /TRACE/NOMAP/EXEC=UUDECODE.EXE uudecode.obj,argproc.obj,crtl.opt/opt X$ CC /NOLIST/OBJECT=UUCAT.OBJ UUCAT.C X$ LINK /TRACE/NOMAP/EXEC=UUCAT.EXE uucat.obj,argproc.obj,crtl.opt/opt X$ ! Done. $ CALL UNPACK VMSBUILD.COM;2 423873605 $ v=f$verify(v) $ EXIT