diff options
Diffstat (limited to 'lib/libpbmvms.c')
-rw-r--r-- | lib/libpbmvms.c | 734 |
1 files changed, 0 insertions, 734 deletions
diff --git a/lib/libpbmvms.c b/lib/libpbmvms.c deleted file mode 100644 index 8a2a54f8..00000000 --- a/lib/libpbmvms.c +++ /dev/null @@ -1,734 +0,0 @@ -/*************************************************************************** - This file contains library routines needed to build Netpbm for VMS. - However, as of 2000.05.26, when these were split out of libpbm1.c - (where they were all switched by #ifdef VMS), there is no evidence - that anyone is building Netpbm for VMS. -****************************************************************************/ - -/* - * @(#)argproc.c 1.0 89/02/01 Mark Pizzolato (mark@infopiz.uucp) - */ - -#ifndef lint -char argproc_version[] = "@(#)argproc.c VMS uucp Version infopiz-1.0"; -#endif - -#include "includes.h" /* System include files, system dependent */ - - -/* - * getredirection() is intended to aid in porting C programs - * to VMS (Vax-11 C) which does not have '>' and '<' - * I/O redirection, along with a command line pipe mechanism - * using the '|' AND background command execution '&'. - * The piping mechanism will probably work with almost any 'filter' type - * of program. With suitable modification, it may useful for other - * portability problems as well. - * - * Author: Mark Pizzolato mark@infopiz.UUCP - */ -struct list_item - { - struct list_item *next; - char *value; - }; - -int -getredirection(ac, av) -int *ac; -char ***av; -/* - * Process vms redirection arg's. Exit if any error is seen. - * If getredirection() processes an argument, it is erased - * from the vector. getredirection() returns a new argc and argv value. - * In the event that a background command is requested (by a trailing "&"), - * this routine creates a background subprocess, and simply exits the program. - * - * Warning: do not try to simplify the code for vms. The code - * presupposes that getredirection() is called before any data is - * read from stdin or written to stdout. - * - * Normal usage is as follows: - * - * main(argc, argv) - * int argc; - * char *argv[]; - * { - * getredirection(&argc, &argv); - * } - */ -{ - int argc = *ac; /* Argument Count */ - char **argv = *av; /* Argument Vector */ - char *ap; /* Argument pointer */ - int j; /* argv[] index */ - extern int errno; /* Last vms i/o error */ - int item_count = 0; /* Count of Items in List */ - int new_file; /* flag, true if '>' used */ - struct list_item *list_head = 0; /* First Item in List */ - struct list_item *list_tail; /* Last Item in List */ - char *in = NULL; /* Input File Name */ - char *out = NULL; /* Output File Name */ - char *outmode = "w"; /* Mode to Open Output File */ - int cmargc = 0; /* Piped Command Arg Count */ - char **cmargv = NULL;/* Piped Command Arg Vector */ - stat_t statbuf; /* fstat buffer */ - - /* - * First handle the case where the last thing on the line ends with - * a '&'. This indicates the desire for the command to be run in a - * subprocess, so we satisfy that desire. - */ - ap = argv[argc-1]; - if (0 == strcmp("&", ap)) - exit(background_process(--argc, argv)); - if ('&' == ap[strlen(ap)-1]) - { - ap[strlen(ap)-1] = '\0'; - exit(background_process(argc, argv)); - } - /* - * Now we handle the general redirection cases that involve '>', '>>', - * '<', and pipes '|'. - */ - for (new_file = 0, j = 0; j < argc; ++j) - { - if (0 == strcmp("<", argv[j])) - { - if (j+1 >= argc) - { - errno = EINVAL; - perror("No input file"); - exit(EXIT_ERR); - } - in = argv[++j]; - continue; - } - if ('<' == *(ap = argv[j])) - { - in = 1 + ap; - continue; - } - if (0 == strcmp(">", ap)) - { - if (j+1 >= argc) - { - errno = EINVAL; - perror("No output file"); - exit(EXIT_ERR); - } - out = argv[++j]; - new_file = 1; - continue; - } - if ('>' == *ap) - { - if ('>' == ap[1]) - { - outmode = "a"; - if ('\0' == ap[2]) - out = argv[++j]; - else - out = 2 + ap; - } - else - { out = 1 + ap; new_file = 1; } - continue; - } - if (0 == strcmp("|", argv[j])) - { - if (j+1 >= argc) - { - errno = EPIPE; - perror("No command to Pipe to"); - exit(EXIT_ERR); - } - cmargc = argc-(j+1); - cmargv = &argv[j+1]; - argc = j; - outmode = "wb"; /* pipes are binary mode devices */ - continue; - } - if ('|' == *(ap = argv[j])) - { - ++argv[j]; - cmargc = argc-j; - cmargv = &argv[j]; - argc = j; - outmode = "wb"; /* pipes are binary mode devices */ - continue; - } - expand_wild_cards(ap, &list_head, &list_tail, &item_count); - } - /* - * Allocate and fill in the new argument vector, Some Unix's terminate - * the list with an extra null pointer. - */ - argv = *av = calloc(item_count+1, sizeof(char *)); - for (j = 0; j < item_count; ++j, list_head = list_head->next) - argv[j] = list_head->value; - *ac = item_count; - if (cmargv != NULL) - { - char subcmd[1024]; - static char *pipe_and_fork(); - - if (out != NULL) - { - errno = EINVAL; - perror("Invalid '|' and '>' specified"); - exit(EXIT_ERR); - } - strcpy(subcmd, cmargv[0]); - for (j = 1; j < cmargc; ++j) - { - strcat(subcmd, " \""); - strcat(subcmd, cmargv[j]); - strcat(subcmd, "\""); - } - out = pipe_and_fork(subcmd); - outmode = "wb"; - } - - /* Check for input from a pipe (mailbox) */ - - if(fstat(0, &statbuf) == 0){ - if(strncmp(statbuf.st_dev, "MB", 2) == 0 || - strncmp(statbuf.st_dev, "_MB", 3) == 0){ - - /* Input from a pipe, reopen it in binary mode to disable */ - /* carriage control processing. */ - - if (in != NULL){ - errno = EINVAL; - perror("Invalid '|' and '<' specified"); - exit(EXIT_ERR); - } - freopen(statbuf.st_dev, "rb", stdin); - } - } - else { - perror("fstat failed"); - exit(EXIT_ERR); - } - -#ifdef __ALPHA - /*, "mbc=32", "mbf=2"))) blows up on the ALPHA cbm 11/08/92 */ - if ((in != NULL) && (NULL == freopen(in, "r", stdin))) - { -#else - if ((in != NULL) && (NULL == freopen(in, "r", stdin, "mbc=32", "mbf=2"))) - { -#endif - perror(in); /* Can't find file */ - exit(EXIT_ERR); /* Is a fatal error */ - } -#ifdef __ALPHA - if ((out != NULL) && (NULL == freopen(out, outmode, stdout))) - { -#else - if ((out != NULL) && (NULL == freopen(out, outmode, stdout, "mbc=32", "mbf=2"))) - { -#endif - perror(ap); /* Error, can't write or append */ - exit(EXIT_ERR); /* Is a fatal error */ - } - - if ( new_file ) { - /* - * We are making an explicit output file, fstat the file and - * declare exit handler to be able change the file to fixed length - * records if necessary. - */ - char fname[256]; - static int outfile_rundown(), check_outfile_filetype(); - static stat_t ofile_stat; - static struct exit_control_block { - struct exit_control_block *flink; - int (*exit_routine)(); - int arg_count; - int *status_address; /* arg 1 */ - stat_t *stat; /* arg 2 */ - int exit_status; - int skew[128]; - } exit_block = - { 0, outfile_rundown, 2, &exit_block.exit_status, &ofile_stat, 0 }; - - if ( fstat ( fileno(stdout), &ofile_stat ) == 0 ) - sys$dclexh ( &exit_block ); - else fprintf(stderr,"Error fstating stdout - %s\n", - strerror(errno,vaxc$errno) ); - - if ( fgetname ( stdout, fname, 0 ) ) check_outfile_filetype ( fname ); - } -#ifdef DEBUG - fprintf(stderr, "Arglist:\n"); - for (j = 0; j < *ac; ++j) - fprintf(stderr, "argv[%d] = '%s'\n", j, argv[j]); -#endif -} - -static int binary_outfile = 0; -void set_outfile_binary() { binary_outfile = 1; return; } - -/* - * Check if output file should be set to binary (fixed 512) on exit based - * upon the filetype. - */ -static int check_outfile_filetype ( name ) - char *name; -{ - char *binary_filetypes, *ext, *p, *t; - binary_filetypes = (char *) getenv ( "PBM_BINARY_FILETYPES" ); - if ( binary_filetypes == NULL ) return 0; - - ext = strchr ( name, '.' ); if ( ext == NULL ) return 0; - ext++; - t = strrchr ( name, '.' ); if ( t != NULL ) *t = '\0'; - - for ( p = binary_filetypes; *p != '\0'; p++ ) { - for ( t = p; - (*p != '\0' ) && (strchr ( ", ", *p ) == NULL); - p++ ) *p = toupper(*p); - *p = '\0'; - - if ( strcmp ( t, ext ) == 0 ) { - binary_outfile = 1; - break; - } - } - return binary_outfile; -} - - -/* - * Exit handler to set output file to binary on image exit. - */ -static int outfile_rundown ( reason, statbuf ) - int *reason; - stat_t *statbuf; -{ - int code, channel, status, LIB$GETDVI(), sys$assign(), sys$qiow(); - long int fib_desc[2], devchar; - short int iosb[4]; - $DESCRIPTOR(device, statbuf->st_dev); - struct fibdef fib; /* File information block (XQP) */ - struct atrdef atr[2]; - struct fat { - unsigned char rtype, ratattrib; - unsigned short int rsize, hiblk[2], efblk[2], ffbyte, maxrec, defext, gbc; - unsigned short int reserved[4], versions; - } rat; - - if ( !binary_outfile ) return 1; /* leave file alone */ - /* - * Assign channel to device listed in stat block and test if it is - * a directory structured device, returning if not. - */ - device.dsc$w_length = strlen ( statbuf->st_dev ); - status = sys$assign ( &device, &channel, 0, 0 ); - if ((status & 1) == 0) { fprintf(stderr, - "assign error to %s (%d)\n", device.dsc$a_pointer, status); - return status; } - code = DVI$_DEVCHAR; - status = LIB$GETDVI ( &code, &channel, 0, &devchar ); - if ((status & 1) == 0) { fprintf(stderr, "getdvi error: %d\n", status); - return status; } - if ( (devchar & DEV$M_DIR) == 0 ) return 1; - /* - * Build File Information Block and Atrribute block. - */ -#ifdef __ALPHA - fib.fib$w_fid[0] = statbuf->st_ino[0]; - fib.fib$w_fid[1] = statbuf->st_ino[1]; - fib.fib$w_fid[2] = statbuf->st_ino[2]; -#else - fib.fib$r_fid_overlay.fib$w_fid[0] = statbuf->st_ino[0]; - fib.fib$r_fid_overlay.fib$w_fid[1] = statbuf->st_ino[1]; - fib.fib$r_fid_overlay.fib$w_fid[2] = statbuf->st_ino[2]; -#endif - - atr[0].atr$w_size = sizeof(rat); - atr[0].atr$w_type = ATR$C_RECATTR; - atr[0].atr$l_addr = &rat; - atr[1].atr$w_size = 0; atr[1].atr$w_type = 0; - /* - * Perform access function with read_attributes sub-function. - */ - freopen ( "SYS$OUTPUT:", "a", stdout ); - fib_desc[0] = 10; fib_desc[1] = (long int) &fib; -#ifdef __ALPHA - fib.fib$l_acctl = FIB$M_WRITE; -#else - fib.fib$r_acctl_overlay.fib$l_acctl = FIB$M_WRITE; -#endif - status = sys$qiow ( 0, channel, IO$_ACCESS|IO$M_ACCESS, - &iosb, 0, 0, &fib_desc, 0, 0, 0, &atr, 0 ); - /* - * If status successful, update record byte and perform a MODIFY. - */ - if ( (status&1) == 1 ) status = iosb[0]; - if ( (status&1) == 1 ) { - rat.rtype = 1; /* fixed length records */ - rat.rsize = 512; /* 512 byte block recrods */ - rat.ratattrib = 0; /* Record attributes: none */ - - status = sys$qiow - ( 0, channel, IO$_MODIFY, &iosb, 0, 0, &fib_desc, 0, 0, 0, &atr, 0 ); - if ( (status&1) == 1 ) status = iosb[0]; - } - sys$dassgn ( channel ); - if ( (status & 1) == 0 ) fprintf ( stderr, - "Failed to convert output file to binary format, status: %d\n", status); - return status; -} - - -static add_item(head, tail, value, count) -struct list_item **head; -struct list_item **tail; -char *value; -int *count; -{ - if (*head == 0) - { - if (NULL == (*head = calloc(1, sizeof(**head)))) - { - errno = ENOMEM; - perror(""); - exit(EXIT_ERR); - } - *tail = *head; - } - else - if (NULL == ((*tail)->next = calloc(1, sizeof(**head)))) - { - errno = ENOMEM; - perror(""); - exit(EXIT_ERR); - } - else - *tail = (*tail)->next; - (*tail)->value = value; - ++(*count); -} - -static expand_wild_cards(item, head, tail, count) -char *item; -struct ltem_list **head; -struct ltem_list **tail; -int *count; -{ -int expcount = 0; -int context = 0; -int status; -int status_value; -int had_version; -$DESCRIPTOR(filespec, item); -$DESCRIPTOR(defaultspec, "SYS$DISK:[]*.*;"); -$DESCRIPTOR(resultspec, ""); - - if (strcspn(item, "*%") == strlen(item)) - { - add_item(head, tail, item, count); - return; - } - resultspec.dsc$b_dtype = DSC$K_DTYPE_T; - resultspec.dsc$b_class = DSC$K_CLASS_D; - resultspec.dsc$a_pointer = NULL; - filespec.dsc$w_length = strlen(item); - /* - * Only return version specs, if the caller specified a version - */ - had_version = strchr(item, ';'); - while (1 == (1&lib$find_file(&filespec, &resultspec, &context, - &defaultspec, 0, &status_value, &0))) - { - char *string; - char *c; - - if (NULL == (string = calloc(1, resultspec.dsc$w_length+1))) - { - errno = ENOMEM; - perror(""); - exit(EXIT_ERR); - } - strncpy(string, resultspec.dsc$a_pointer, resultspec.dsc$w_length); - string[resultspec.dsc$w_length] = '\0'; - if (NULL == had_version) - *((char *)strrchr(string, ';')) = '\0'; - /* - * Be consistent with what the C RTL has already done to the rest of - * the argv items and lowercase all of these names. - */ - for (c = string; *c; ++c) - if (isupper(*c)) - *c = tolower(*c); - add_item(head, tail, string, count); - ++expcount; - } - if (expcount == 0) - add_item(head, tail, item, count); - lib$sfree1_dd(&resultspec); - lib$find_file_end(&context); -} - -static int child_st[2]; /* Event Flag set when child process completes */ - -static short child_chan;/* I/O Channel for Pipe Mailbox */ - -static exit_handler(status) -int *status; -{ -short iosb[4]; - - if (0 == child_st[0]) - { -#ifdef DEBUG - fprintf(stderr, "Waiting for Child Process to Finnish . . .\n"); -#endif - fflush(stdout); /* Have to flush pipe for binary data to */ - /* terminate properly -- <tp@mccall.com> */ -#ifdef DEBUG - fprintf(stderr, " stdout flushed. . .\n"); -#endif - sys$qio(0, child_chan, IO$_WRITEOF, iosb, 0, 0, 0, 0, 0, 0, 0, 0); -#ifdef DEBUG - fprintf(stderr, " Pipe terminated. . .\n"); -#endif - fclose(stdout); -#ifdef DEBUG - fprintf(stderr, " stdout closed. . .\n"); -#endif - sys$synch(0, child_st); - sys$dassgn(child_chan); - } -#ifdef DEBUG - fprintf(stderr, " sync done. . .\n"); -#endif -} - -#include <syidef> /* System Information Definitions */ - -static sig_child(chan) -int chan; -{ -#ifdef DEBUG - fprintf(stderr, "Child Completion AST, st: %x\n", child_st[0] ); -#endif - if (child_st[0] == 0) - { child_st[0] = 1; } - sys$setef ( 0 ); -} - -static struct exit_control_block - { - struct exit_control_block *flink; - int (*exit_routine)(); - int arg_count; - int *status_address; - int exit_status; - } exit_block = - { - 0, - exit_handler, - 1, - &exit_block.exit_status, - 0 - }; - -static char *pipe_and_fork(cmd) -char *cmd; -{ - $DESCRIPTOR(cmddsc, cmd); - static char mbxname[64], ef = 0; - $DESCRIPTOR(mbxdsc, mbxname); - short iosb[4]; - int status; - int pid; - struct - { - short dna_buflen; - short dna_itmcod; - char *dna_buffer; - short *dna_retlen; - int listend; - } itmlst = - { - sizeof(mbxname), - DVI$_DEVNAM, - mbxname, - &mbxdsc.dsc$w_length, - 0 - }; - int mbxsize; - struct - { - short mbf_buflen; - short mbf_itmcod; - int *mbf_maxbuf; - short *mbf_retlen; - int listend; - } syiitmlst = - { - sizeof(mbxsize), - SYI$_MAXBUF, - &mbxsize, - 0, - 0 - }; - - cmddsc.dsc$w_length = strlen(cmd); - /* - * Get the SYSGEN parameter MAXBUF, and the smaller of it and 2048 as - * the size of the 'pipe' mailbox. - */ - if (1 == (1&(vaxc$errno = sys$getsyiw(0, 0, 0, &syiitmlst, iosb, 0, 0, 0)))) - vaxc$errno = iosb[0]; - if (0 == (1&vaxc$errno)) - { - errno = EVMSERR; - perror("Can't get SYSGEN parameter value for MAXBUF"); - exit(EXIT_ERR); - } - if (mbxsize > 2048) - mbxsize = 2048; - if (0 == (1&(vaxc$errno = sys$crembx(0, &child_chan, mbxsize, mbxsize, 0, 0, 0)))) - { - errno = EVMSERR; - perror("Can't create pipe mailbox"); - exit(EXIT_ERR); - } - if (1 == (1&(vaxc$errno = sys$getdviw(0, child_chan, 0, &itmlst, iosb, - 0, 0, 0)))) - vaxc$errno = iosb[0]; - if (0 == (1&vaxc$errno)) - { - errno = EVMSERR; - perror("Can't get pipe mailbox device name"); - exit(EXIT_ERR); - } - mbxname[mbxdsc.dsc$w_length] = '\0'; -#ifdef DEBUG - fprintf(stderr, "Pipe Mailbox Name = '%s'\n", mbxname); -#endif - if (0 == (1&(vaxc$errno = lib$spawn(&cmddsc, &mbxdsc, 0, &1, - 0, &pid, child_st, &ef, sig_child, - &child_chan)))) - { - errno = EVMSERR; - perror("Can't spawn subprocess"); - exit(EXIT_ERR); - } -#ifdef DEBUG - fprintf(stderr, "Subprocess's Pid = %08X\n", pid); -#endif - sys$dclexh(&exit_block); - return(mbxname); -} - -background_process(argc, argv) -int argc; -char **argv; -{ -char command[2048] = "$"; -$DESCRIPTOR(value, command); -$DESCRIPTOR(cmd, "BACKGROUND$COMMAND"); -$DESCRIPTOR(null, "NLA0:"); -int pid; - - strcat(command, argv[0]); - while (--argc) - { - strcat(command, " \""); - strcat(command, *(++argv)); - strcat(command, "\""); - } - value.dsc$w_length = strlen(command); - if (0 == (1&(vaxc$errno = lib$set_symbol(&cmd, &value)))) - { - errno = EVMSERR; - perror("Can't create symbol for subprocess command"); - exit(EXIT_ERR); - } - if (0 == (1&(vaxc$errno = lib$spawn(&cmd, &null, 0, &17, 0, &pid)))) - { - errno = EVMSERR; - perror("Can't spawn subprocess"); - exit(EXIT_ERR); - } -#ifdef DEBUG - fprintf(stderr, "%s\n", command); -#endif - fprintf(stderr, "%08X\n", pid); - return(EXIT_OK); -} - -/* got this off net.sources */ - -#ifdef VMS -#define index strchr -#endif /*VMS*/ - -/* - * get option letter from argument vector - */ -int opterr = 1, /* useless, never set or used */ - optind = 1, /* index into parent argv vector */ - optopt; /* character checked for validity */ -char *optarg; /* argument associated with option */ - -#define BADCH (int)'?' -#define EMSG "" -#define tell(s) fputs(progname,stderr);fputs(s,stderr); \ - fputc(optopt,stderr);fputc('\n',stderr);return(BADCH); - -getopt(nargc,nargv,ostr) -int nargc; -char **nargv, - *ostr; -{ - static char *place = EMSG; /* option letter processing */ - register char *oli; /* option letter list index */ - char *index(); - char *progname; - - if(!*place) { /* update scanning pointer */ - if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) return(EOF); - if (*place == '-') { /* found "--" */ - ++optind; - return(EOF); - } - } /* option letter okay? */ - if ((optopt = (int)*place++) == (int)':' || !(oli = index(ostr,optopt))) { - if(!*place) ++optind; -#ifdef VMS - progname = strrchr(nargv[0],']'); -#else - progname = rindex(nargv[0],'/'); -#endif - if (!progname) progname = nargv[0]; else progname++; - tell(": illegal option -- "); - } - if (*++oli != ':') { /* don't need argument */ - optarg = NULL; - if (!*place) ++optind; - } - else { /* need an argument */ - if (*place) optarg = place; /* no white space */ - else if (nargc <= ++optind) { /* no arg */ - place = EMSG; -#ifdef VMS - progname = strrchr(nargv[0],']'); -#else - progname = rindex(nargv[0],'/'); -#endif - if (!progname) progname = nargv[0]; else progname++; - tell(": option requires an argument -- "); - } - else optarg = nargv[optind]; /* white space */ - place = EMSG; - ++optind; - } - return(optopt); /* dump back option letter */ -} |