home *** CD-ROM | disk | FTP | other *** search
/ Mega CD-ROM 1 / megacd_rom_1.zip / megacd_rom_1 / GNUISH / SWALIB0.ZIP / SW_ENV.C < prev    next >
C/C++ Source or Header  |  1990-09-10  |  4KB  |  179 lines

  1. /* sw_env.c - build a well formed MS-DOS environment.
  2.    Copyright (C) 1990 by Thorsten Ohl, td12@ddagsi3.bitnet
  3.  
  4.    This file is part of SWAPLIB (the library), a library for efficient
  5.    execution of child processes under MS-DOS.
  6.  
  7.    The library is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 1, or (at your option)
  10.    any later version.
  11.  
  12.    The library is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with the library; if not, write to the Free Software
  19.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.    $Header: e:/gnu/swaplib/RCS/sw_env.c'v 0.9 90/09/09 21:43:55 tho Stable $
  22.  */
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <stdarg.h>
  28. #include <ctype.h>
  29.  
  30. #include "swaplib.h"
  31.  
  32. extern void *xmalloc (size_t size);
  33. extern void *xrealloc (void *ptr, size_t size);
  34. static int argv_p (char *s);
  35.  
  36.  
  37. /* Test whether S is an environment entry used to pass
  38.    commandline arguments.  We use it to filter such
  39.    entries out that migth have been installed by lower
  40.    shell levels.  */
  41.  
  42. int
  43. argv_p (char *s)
  44. {
  45.   if (!strncmp (s, "_argc=", 6))    /* Easy match. */
  46.     return 1;
  47.   else
  48.     {
  49.       if (strncmp (s, "_argv", 5))    /* Prefix failed.  */
  50.     return 0;
  51.       else
  52.     {
  53.       s += 5;
  54.       while (isdigit (*s))        /* Skip digits. */
  55.         s++;
  56.       if (*s == '=')
  57.         return 1;
  58.       else
  59.         return 0;
  60.     }
  61.     }
  62. }
  63.  
  64.  
  65. /* Build a well formed MS-DOS environment (ASCIZ strings,
  66.    terminated by another '\0') from ENVV.  If ENVV is NULL,
  67.    use ENVIRON.  If ARGV is not NULL,  prepend it by
  68.    "_argv0="ARGV[0], "_argv1="ARGV[1], ..., "_argc="ARGC.
  69.     This is the way to pass a 32k commandline.  Additional
  70.    entries can be specified by the NULL terminated list of
  71.    optional arguments.  Neither of the arguments will be freed.
  72.    The result will be stored in BUFPTR and the total length of
  73.    the environment (including '\0''s) is returned.  */
  74.  
  75. #define ALLOC_UNIT    0x0200
  76. #define EXPAND_BUFFER                        \
  77.   while (allocated <= used + size)                \
  78.     {                                \
  79.       allocated += ALLOC_UNIT;                    \
  80.       _swap_environ_buf                        \
  81.     = (char *) xrealloc (_swap_environ_buf, allocated);    \
  82.     }
  83.  
  84. int
  85. _swap_format_msdos_environment (char **argv, char **envv, ...)
  86. {
  87.   int allocated = 0;
  88.   int size = 0;
  89.   int used = 0;
  90.   int argc = 0;
  91.  
  92.   /* further optional entries: */
  93.  
  94.   va_list optarg;
  95.   char *entry = NULL;
  96.  
  97.  
  98.   if (argv)
  99.     {
  100.       /* Format the commandline arguments as environment entries.  */
  101.  
  102.       while (*argv)
  103.     {
  104.       size = strlen (*argv) + sizeof ("_argv32767=") + 1;
  105.       EXPAND_BUFFER;
  106.       used += sprintf (_swap_environ_buf + used, "_argv%d=%s",
  107.                argc++, *argv++) + 1;
  108.     }
  109.  
  110.       /* Store the number of arguments.  */
  111.  
  112.       if (argc > 0)
  113.     {
  114.       size = sizeof ("_argc=32767") + 1;
  115.       EXPAND_BUFFER;
  116.       used += sprintf (_swap_environ_buf + used, "_argc=%d", argc) + 1;
  117.     }
  118.     }
  119.  
  120.   /* Process the optional arguments.  */
  121.  
  122.   va_start (optarg, envv);
  123.  
  124.   while (1)
  125.     {
  126.       entry = va_arg (optarg, char *);
  127.       if (!entry)
  128.     break;
  129.  
  130.       size = strlen (entry) + 2;
  131.       EXPAND_BUFFER;
  132.       strcpy (_swap_environ_buf + used, entry);
  133.       used += size - 1;
  134.     }
  135.  
  136.   va_end (optarg);
  137.  
  138.  
  139.   /* Maybe export the standard environment.  */
  140.  
  141.   if (!envv)
  142.     envv = environ;
  143.  
  144.   /* Now copy the environment.  */
  145.  
  146.   while (*envv)
  147.     {
  148.       /*  Avoid stacking the commandline entries.  */
  149.  
  150.       if (!argv_p (*envv))
  151.     {
  152.       size = strlen (*envv) + 2;
  153.       EXPAND_BUFFER;
  154.       strcpy (_swap_environ_buf + used, *envv);
  155.       used += size - 1;
  156.     }
  157.       envv++;
  158.     }
  159.  
  160.   /* MS-DOS Environments end with "\000\000".  */
  161.  
  162.   _swap_environ_buf[used++] = '\0';
  163.  
  164.   /* Release useless storage.  */
  165.  
  166.   _swap_environ_buf = (char *) xrealloc (_swap_environ_buf, used);
  167.  
  168.   return used;
  169. }
  170.  
  171. /* 
  172.  * Local Variables:
  173.  * mode:C
  174.  * ChangeLog:ChangeLog
  175.  * compile-command:make
  176.  * End:
  177.  */
  178.  
  179.