home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / unzip52.zip / envargs.c < prev    next >
C/C++ Source or Header  |  1996-01-05  |  6KB  |  225 lines

  1. /*----------------------------------------------------------------*
  2.  | envargs - add default options from environment to command line
  3.  |----------------------------------------------------------------
  4.  | Author: Bill Davidsen, original 10/13/91, revised 23 Oct 1991.
  5.  | This program is in the public domain.
  6.  |----------------------------------------------------------------
  7.  | Minor program notes:
  8.  |  1. Yes, the indirection is a tad complex
  9.  |  2. Parenthesis were added where not needed in some cases
  10.  |     to make the action of the code less obscure.
  11.  |  3. Set tabsize to four to make this pretty
  12.  |----------------------------------------------------------------
  13.  | UnZip notes: 24 May 92 ("v1.4"):
  14.  |  1. #include "unzip.h" for prototypes (24 May 92)
  15.  |  2. changed ch to type char (24 May 92)
  16.  |  3. added an ifdef to avoid Borland warnings (24 May 92)
  17.  |  4. included Rich Wales' mksargs() routine (for MS-DOS, maybe
  18.  |     OS/2? NT?) (4 Dec 93)
  19.  |  5. added alternate-variable string envstr2 (21 Apr 94)
  20.  *----------------------------------------------------------------*/
  21.  
  22.  
  23. #define UNZIP_INTERNAL
  24. #include "unzip.h"
  25.  
  26. static int count_args OF((char *));
  27. static void mem_err OF((__GPRO));
  28.  
  29. #if (defined(SCCS) && !defined(lint))  /* causes warnings:  annoying */
  30.    static char *SCCSid = "@(#)envargs.c    1.3 23 Oct 1991";
  31. #endif
  32.  
  33. static char Far NoMemArguments[] = "envargs:  can't get memory for arguments";
  34.  
  35.  
  36.  
  37. void envargs(__G__ Pargc, Pargv, envstr, envstr2)
  38.     __GDEF
  39.     int *Pargc;
  40.     char ***Pargv, *envstr, *envstr2;
  41. {
  42. #ifndef RISCOS
  43.     char *getenv();
  44. #endif
  45.     char *envptr;       /* value returned by getenv */
  46.     char *bufptr;       /* copy of env info */
  47.     int argc = 0;       /* internal arg count */
  48.     char ch;            /* spare temp value */
  49.     char **argv;        /* internal arg vector */
  50.     char **argvect;     /* copy of vector address */
  51.  
  52.     /* see if anything in either of valid environment variables */
  53.     if ((envptr = getenv(envstr)) == (char *)NULL || *envptr == 0)
  54.         if ((envptr = getenv(envstr2)) == (char *)NULL || *envptr == 0)
  55.             return;
  56.  
  57.     /* count the args so we can allocate room for them */
  58.     argc = count_args(envptr);
  59.     bufptr = (char *)malloc(1+strlen(envptr));
  60.     if (bufptr == (char *)NULL)
  61.         mem_err(__G);
  62.     strcpy(bufptr, envptr);
  63.  
  64.     /* allocate a vector large enough for all args */
  65.     argv = (char **)malloc((argc+*Pargc+1)*sizeof(char *));
  66.     if (argv == (char **)NULL)
  67.         mem_err(__G);
  68.     argvect = argv;
  69.  
  70.     /* copy the program name first, that's always true */
  71.     *(argv++) = *((*Pargv)++);
  72.  
  73.     /* copy the environment args next, may be changed */
  74.     do {
  75.         *(argv++) = bufptr;
  76.         /* skip the arg and any trailing blanks */
  77.         while (((ch = *bufptr) != '\0') && ch != ' ')
  78.             ++bufptr;
  79.         if (ch == ' ')
  80.             *(bufptr++) = '\0';
  81.         while (((ch = *bufptr) != '\0') && ch == ' ')
  82.             ++bufptr;
  83.     } while (ch);
  84.  
  85.     /* now save old argc and copy in the old args */
  86.     argc += *Pargc;
  87.     while (--(*Pargc))
  88.         *(argv++) = *((*Pargv)++);
  89.  
  90.     /* finally, add a NULL after the last arg, like UNIX */
  91.     *argv = (char *)NULL;
  92.  
  93.     /* save the values and return */
  94.     *Pargv = argvect;
  95.     *Pargc = argc;
  96. }
  97.  
  98.  
  99.  
  100. static int count_args(s)
  101.     char *s;
  102. {
  103.     int count = 0;
  104.     char ch;
  105.  
  106.     do {
  107.         /* count and skip args */
  108.         ++count;
  109.         while (((ch = *s) != '\0') && ch != ' ')
  110.             ++s;
  111.         while (((ch = *s) != '\0') && ch == ' ')
  112.             ++s;
  113.     } while (ch);
  114.  
  115.     return count;
  116. }
  117.  
  118.  
  119.  
  120. static void mem_err(__G)
  121.     __GDEF
  122. {
  123.     perror(LoadFarString(NoMemArguments));
  124.     DESTROYGLOBALS()
  125.     EXIT(2);
  126. }
  127.  
  128.  
  129.  
  130. #ifdef TEST
  131.  
  132. main(argc, argv)
  133.     int argc;
  134.     char **argv;
  135. {
  136.     int i;
  137.  
  138.     printf("Orig argv: %p\n", argv);
  139.     dump_args(argc, argv);
  140.     envargs(__G__ &argc, &argv, "ENVTEST");
  141.     printf(" New argv: %p\n", argv);
  142.     dump_args(argc, argv);
  143. }
  144.  
  145.  
  146.  
  147. dump_args(argc, argv)
  148.     int argc;
  149.     char *argv[];
  150. {
  151.     int i;
  152.  
  153.     printf("\nDump %d args:\n", argc);
  154.     for (i = 0; i < argc; ++i)
  155.         printf("%3d %s\n", i, argv[i]);
  156. }
  157.  
  158. #endif /* TEST */
  159.  
  160.  
  161.  
  162. #ifdef MSDOS   /* DOS_OS2?  DOS_OS2_W32? */
  163.  
  164. /*
  165.  * void mksargs(int *argcp, char ***argvp)
  166.  *
  167.  *    Substitutes the extended command line argument list produced by
  168.  *    the MKS Korn Shell in place of the command line info from DOS.
  169.  *
  170.  *    The MKS shell gets around DOS's 128-byte limit on the length of
  171.  *    a command line by passing the "real" command line in the envi-
  172.  *    ronment.  The "real" arguments are flagged by prepending a tilde
  173.  *    (~) to each one.
  174.  *
  175.  *    This "mksargs" routine creates a new argument list by scanning
  176.  *    the environment from the beginning, looking for strings begin-
  177.  *    ning with a tilde character.  The new list replaces the original
  178.  *    "argv" (pointed to by "argvp"), and the number of arguments
  179.  *    in the new list replaces the original "argc" (pointed to by
  180.  *    "argcp").
  181.  *
  182.  *    Rich Wales
  183.  */
  184. void mksargs(argcp, argvp)
  185.     int *argcp;
  186.     char ***argvp;
  187. {
  188. #ifndef MSC /* declared differently in MSC 7.0 headers, at least */
  189. #ifndef __WATCOMC__
  190.     extern char **environ;          /* environment */
  191. #endif
  192. #endif
  193.     char        **envp;             /* pointer into environment */
  194.     char        **newargv;          /* new argument list */
  195.     char        **argp;             /* pointer into new arg list */
  196.     int         newargc;            /* new argument count */
  197.  
  198.     /* sanity check */
  199.     if (environ == NULL || argcp == NULL || argvp == NULL || *argvp == NULL)
  200.         return;
  201.  
  202.     /* find out how many environment arguments there are */
  203.     for (envp = environ, newargc = 0; *envp != NULL && (*envp)[0] == '~';
  204.          envp++, newargc++)
  205.         ;
  206.     if (newargc == 0)
  207.         return;     /* no environment arguments */
  208.  
  209.     /* set up new argument list */
  210.     newargv = (char **) malloc(sizeof(char **) * (newargc+1));
  211.     if (newargv == NULL)
  212.         return;     /* malloc failed */
  213.  
  214.     for (argp = newargv, envp = environ; *envp != NULL && (*envp)[0] == '~';
  215.          *argp++ = &(*envp++)[1])
  216.         ;
  217.     *argp = NULL;   /* null-terminate the list */
  218.  
  219.     /* substitute new argument list in place of old one */
  220.     *argcp = newargc;
  221.     *argvp = newargv;
  222. }
  223.  
  224. #endif /* MSDOS */
  225.