home *** CD-ROM | disk | FTP | other *** search
- /*
- * JET PAK - HP DeskJet and LaserJet series printer utilities
- *
- * JETUTIL module - miscellaneous utilities
- *
- * Version 1.1 (Public Domain)
- */
-
- /* system include files */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #ifdef __MSDOS__
-
- /* MS-DOS platform specific include files */
- #include <dir.h>
- #include <dos.h>
- #include <time.h>
-
- #endif /* __MSDOS__ */
-
- /* application include files */
- #include "jetutil.h"
-
-
- /*
- * OPTION PROCESSING UTILITY FUNCTIONS
- */
-
- char *optarg = ""; /* option argument (if any) */
- int optind = 1; /* argv[] index currently being examined */
- int opterr = TRUE; /* whether getopt() should print error messages */
-
- static int optpos = 0; /* position in argv[optind] being examined */
-
- #define OPTCHAR '-'
- #define OPTARGCHAR ':'
- #define OPTBAD '?'
-
- int getopt(argc, argv, optstring)
- int argc;
- char *argv[];
- char *optstring;
- {
- /*
- * This function should behave like the UNIX getopt():
- *
- * It returns the next option letter in 'argv[]' that matches a
- * letter in 'optstring'. 'optstring' is a string of recognised
- * option letters; if a letter is followed by ':' (OPTARGCHAR), the
- * option is expected to have an argument, which may or may not
- * be separated from it by white space; 'optarg' is then set to point
- * to the start of the option argument.
- *
- * When all options have been processed, getopt() returns EOF.
- * The special option '--' can be used to mark the end of the
- * options.
- *
- * On error, '?' (OPTBAD) is returned; if 'opterr' is TRUE, an
- * error message is also printed.
- */
- char *osp;
-
- /* check index to argument is in range */
- if (optind < 1 || optind >= argc)
- return(EOF);
-
- if (optpos == 0)
- {
- /* check argument is an option */
- if (argv[optind][optpos] != OPTCHAR)
- return(EOF);
-
- /* check for explicit argument termination */
- if (argv[optind][++optpos] == OPTCHAR)
- {
- optpos = 0;
- optind++;
-
- return(EOF);
- }
- }
-
- /* check option is valid */
- if (!(osp = strchr(optstring, argv[optind][optpos])))
- {
- if (opterr)
- fprintf(stderr, ERROR_OPTION_BAD, argv[optind][optpos]);
-
- if (argv[optind][++optpos] == '\0')
- {
- optpos = 0;
- optind++;
- }
-
- return(OPTBAD);
- }
-
- if (osp[1] == OPTARGCHAR)
- {
- /* argument is expected */
- if (argv[optind][++optpos] == '\0')
- {
- optind++;
- if (optind >= argc)
- {
- fprintf(stderr, ERROR_OPTION_NO_ARG, osp[0]);
- return(OPTBAD);
- }
-
- optarg = argv[optind];
- }
- else
- {
- optarg = &argv[optind][optpos];
- }
-
- optpos = 0;
- optind++;
- }
- else
- {
- /* no arguments required */
- optarg = "";
-
- if (argv[optind][++optpos] == '\0')
- {
- optpos = 0;
- optind++;
- }
- }
-
- return(osp[0]);
- }
-
- /*
- * DIRECTORY SEARCHING UTILITY FUNCTIONS
- */
-
- /* the following exported variables point to the next matching file
- and containing directory to be processed when os_getfile()
- returns OK */
- char *os_file = NULL;
- char *os_dir = NULL;
-
- /* definitions of list nodes used to hold directories and files */
- struct filenode {
- struct filenode *next;
- char *name;
- };
-
- struct dirnode {
- struct dirnode *next;
- char *name;
- struct filenode *file;
- };
-
- static struct dirnode *dirnodeptr = NULL;
-
- int os_findfiles(argc, argv)
- int argc;
- char *argv[];
- {
- /*
- * This function builds a tree structure recording the files
- * selected for processing by the user, and their containing
- * directories.
- *
- * This is needed for MS-DOS to get around the problem that
- * if wildcard matching is done continuously while a program
- * is running, the output files created by the program can
- * start to be matched, and this is not a good thing. For
- * example, JETL2D *.* would cause problems if more than one
- * input file existed in the directory to start with.
- *
- * Path names are split up into directory and file parts so
- * that the output files may be built in the current directory,
- * even if the input files are prefixed with a different
- * directory name.
- *
- * Space is allocated from the heap for the elements of the
- * structure. If there isn't sufficient heap space to
- * build the structure, ERROR is returned. Otherwise OK is
- * returned.
- */
- #ifdef __MSDOS__
- struct ffblk findblock;
- #endif /* __MSDOS__ */
- char *asp;
- struct dirnode *dnp;
- struct filenode *fnp;
- int arg;
-
- for (arg = 0; arg < argc; arg++)
- {
- if (dirnodeptr == NULL)
- {
- if ((dirnodeptr = zalloc(sizeof(struct dirnode))) == NULL)
- return(ERROR);
-
- dnp = dirnodeptr;
- }
- else
- {
- if ((dnp->next = zalloc(sizeof(struct dirnode))) == NULL)
- return(ERROR);
-
- dnp = dnp->next;
- }
-
- /* PLATFORM_DEPENDENT: directory/file separator */
- #ifdef __MSDOS__
- #define PATHNAME_SEPARATOR '\\'
- #else
- #define PATHNAME_SEPARATOR '/'
- #endif
- if ((asp = strrchr(argv[arg], PATHNAME_SEPARATOR)) != NULL)
- {
- /* directory specified in path */
- if ((dnp->name = zalloc((size_t)((asp - argv[arg]) + 2))) == NULL)
- return(ERROR);
- strncpy(dnp->name, argv[arg], (size_t)((asp - argv[arg]) + 1));
- }
- #ifdef __MSDOS__
- else if ((asp = strrchr(argv[arg], ':')) != NULL)
- {
- /* drive name specified in path */
- if ((dnp->name = zalloc((size_t)((asp - argv[arg]) + 2))) == NULL)
- return(ERROR);
- strncpy(dnp->name, argv[arg], (size_t)((asp - argv[arg]) + 1));
- }
- #endif /* __MSDOS__ */
- else
- {
- /* set directory to "" */
- if ((dnp->name = zalloc(1)) == NULL)
- return(ERROR);
- }
-
- #ifdef __MSDOS__
-
- if (findfirst(argv[arg], &findblock, 0) == 0)
- {
- if ((fnp = zalloc(sizeof(struct filenode))) == NULL)
- return(ERROR);
- dnp->file = fnp;
-
- if ((fnp->name = zalloc(1+strlen(findblock.ff_name))) == NULL)
- return(ERROR);
- strcpy(fnp->name, findblock.ff_name);
- strlwr(fnp->name); /* for consistent lower case naming */
-
- while(findnext(&findblock) == 0)
- {
- if ((fnp->next = zalloc(sizeof(struct filenode))) == NULL)
- return(ERROR);
- fnp = fnp->next;
-
- if ((fnp->name = zalloc(1+strlen(findblock.ff_name))) == NULL)
- return(ERROR);
- strcpy(fnp->name, findblock.ff_name);
- strlwr(fnp->name);
- }
- }
- else
- {
- fprintf(stderr, ERROR_NO_FILES_MATCHED, argv[arg]);
- }
-
- #else /* __MSDOS__ */
-
- /* PLATFORM_DEPENDENT: if a non-MSDOS platform requires the
- program to implement wildcard matching itself (ie like MS-DOS),
- then the necessary code to do that could be added in here */
-
- if ((fnp = zalloc(sizeof(struct filenode))) == NULL)
- return(ERROR);
- dnp->file = fnp;
-
- /* point asp at start of file name */
- if (asp == NULL)
- asp = argv[arg];
- else
- asp++;
-
- if ((fnp->name = zalloc(1+strlen(asp))) == NULL)
- return(ERROR);
- strcpy(fnp->name, asp);
-
- #endif /* __MSDOS__ */
-
- }
-
- return(OK);
- }
-
- int os_getfile()
- {
- /*
- * This function is called after os_findfiles() to select in turn
- * each file required to be processed.
- *
- * If os_getfile() finds a file to be processed, it sets the
- * 'os_dir' and 'os_file' globals to point to the containing
- * directory and file name, and returns OK. If there are no
- * more files to be processed, EOF is returned.
- *
- * os_getfile() walks through the node structure built by
- * os_findfiles(), transferring the node pointers to os_dir
- * and os_file, then freeing the heap space once they are
- * no longer needed.
- */
- struct dirnode *dnp;
- struct filenode *fnp;
-
- /* loop through directories looking for a file */
- while ((dnp = dirnodeptr) != NULL)
- {
- /* first time through for a directory, move its name to os_dir */
- if (dnp->name != NULL)
- {
- if (os_dir != NULL)
- free(os_dir);
- os_dir = dnp->name;
- dnp->name = NULL;
- }
-
- while ((fnp = dnp->file) != NULL)
- {
- /* move file name to os_file */
- if (fnp->name != NULL)
- {
- if (os_file != NULL)
- free(os_file);
- os_file = fnp->name;
- dnp->file = fnp->next;
- free(fnp);
- return(OK);
- }
-
- dnp->file = fnp->next;
- free(fnp);
- }
-
- /* no more files in directory, so free node */
- dirnodeptr = dnp->next;
- free(dnp);
- }
-
- /* no more files to be processed, free remaining heap space */
- if (os_dir != NULL)
- free(os_dir);
- if (os_file != NULL)
- free(os_file);
-
- return(EOF);
- }
-
- /*
- * PRINTING UTILITY FUNCTIONS
- */
-
- void os_printstr(s)
- char *s;
- {
- /*
- * Print NULL terminated string 's'
- */
-
- #ifdef __MSDOS__
-
- while (*s) bdos(5, *s++, 0);
-
- #else /* __MSDOS__ */
-
- /* PLATFORM_DEPENDENT: do whatever you have to do to print a
- string on a non-MSDOS platform here */
- while (*s)
- {
- putchar(*s);
- s++;
- }
-
- #endif /* __MSDOS__ */
- }
- void os_printbuf(s, n)
- char *s;
- int n;
- {
- /*
- * Print buffer 's' of length 'n', which may contain NULLs
- */
-
- #ifdef __MSDOS__
-
- while (n-- > 0) bdos(5, *s++, 0);
-
- #else /* __MSDOS__ */
-
- /* PLATFORM_DEPENDENT: do whatever you have to do to print a
- buffer on a non-MSDOS platform here */
- while (n-- > 0)
- {
- putchar(*s);
- s++;
- }
-
- #endif /* __MSDOS__ */
- }
-
- /*
- * MEMORY ALLOCATION FUNCTIONS
- */
-
- void *zalloc(nbytes)
- size_t nbytes;
- {
- /*
- * Allocate and clear nbytes of memory. This routine succeeds
- * even if nbytes is 0
- */
-
- if (nbytes == 0)
- nbytes++;
-
- return(calloc(1, nbytes));
- }
-