home *** CD-ROM | disk | FTP | other *** search
/ Vectronix 2 / VECTRONIX2.iso / FILES_07 / MARK_WC1.LZH / SRC / CSHTOMWC.C < prev    next >
C/C++ Source or Header  |  1988-04-27  |  7KB  |  181 lines

  1. /*
  2.  * Usage: cshtomwc file_name [argument ...]
  3.  *
  4.  * Returns: 1 if anything went wrong, otherwise return status of program.
  5.  *
  6.  * Compile with: cc cshtomwc.c            # for the newest cshell's
  7.  * or with:     cc -DOLDCSHELL cshtomwc.c    # for older cshell's
  8.  *
  9.  * Written by: rec@mwc 1986-10-08
  10.  *
  11.  * This program should allow cshell users to call MWC programs
  12.  * with the following caveats:
  13.  *    1) You must give a complete file name for the program to be run.
  14.  *    Since you'll probably be using this in an alias or a command
  15.  *    file, this should be no great misery.
  16.  *    2) You must setenv the environments which MWC requires
  17.  *    These are listed several times in the MWC documentation.
  18.  *    Start from the lexicon article on 'environment' if you need
  19.  *    review.  (If your cshell doesn't have a 'setenv' command,
  20.  *    keep reading; we have a solution for you, too.)
  21.  *    3) The enviroments must be in MWC format with the exception
  22.  *    of PATH which we may use the cshell list separator.
  23.  *    4) If you redirect standard input to a file or a pipe, the
  24.  *    program you call will not find EOF on standard input.
  25.  *    5) If you redirect standard output to a file, all writes to
  26.  *    stderr will end up there, too.
  27.  *
  28.  * The first version of this program was produced from a Beckemeyer
  29.  * environment/argument passing specification dated 9/30/86.  The
  30.  * version of the cshell which we have does not follow the specification,
  31.  * it passes random binary garbage in the basepage.p_env.  The multi-
  32.  * tasking cshell does follow the specification.  We don't know when he
  33.  * added the environment/argument passing conventions to his product.
  34.  * If your cshell has no 'setenv' command, or if this program doesn't
  35.  * work when compiled with 'cc cshtomwc.c', then you should:
  36.  *    1) Edit the strings in the defenv array below to reflect
  37.  *    your system's configuration.
  38.  *    2) Compile with 'cc -DOLDCSHELL cshtomwc.c' to eliminate
  39.  *    the Beckemeyer anachronisms.
  40.  */
  41. #include <basepage.h>        /* To find the environment string */
  42. #include <assert.h>        /* To find impossibilities */
  43. #include <osbind.h>        /* To have a good time */
  44.  
  45. #ifdef OLDCSHELL
  46. /*
  47.  * This only applies to older cshell's which have no environment.
  48.  * Edit these strings to match your system's layout.
  49.  * Note that they almost certainly won't work as they are.
  50.  * Be sure to preserve the doubled backslashes, or the c compiler
  51.  * will make some unprintable characters for you.
  52.  */
  53. char *defenv[] = {
  54.     "PATH=.bin,,a:\\bin,b:\\bin",
  55.     "SUFF=,.prg,.tos,.ttp",
  56.     "TMPDIR=a:\\tmp",
  57.     "INCDIR=a:\\include",
  58.     "LIBPATH=a:\\lib,b:\\lib",
  59.     0
  60. };
  61. #endif
  62.  
  63. main(argc, argv, envp) int argc; char *argv[], *envp[];
  64. {
  65. #ifndef OLDCSHELL
  66.     {
  67.     /*
  68.      * The first order of business is to fixup the environment.
  69.      * Beckemeyer uses a "name=", "value" format which is
  70.      *    a) incompatible with U**X or Coherent,
  71.      *    b) incapable of passing empty values.
  72.      * We have to reparse p_env from scratch
  73.      * because our run time startup truncated envp[]
  74.      * when it found "ARGV=".
  75.      * But envp[], and argv[] which follows it in memory,
  76.      * will have plenty of room for the resulting vector
  77.      * since we're halving the number of strings.
  78.      * And p_env will have plenty of room since we're
  79.      * simply deleting NUL's and packing the result.
  80.      */
  81.     register char *p1, *p2, **vp;
  82.     vp = envp;            /* passed by crts0.o */
  83.     p1 = p2 = (char *)BP->p_env;    /* Get the start */
  84.     do {
  85.         *vp++ = p1;    /* set envp[x] */
  86.         while (*p1++ = *p2++)    /* copy "name=" to NUL */
  87.             ;
  88.         --p1;            /* scrap NUL */
  89.         while (*p1++ = *p2++)    /* concatenate "value" to NUL */
  90.             ;
  91.     } while (*p2 != 0);    /* until you see two NUL's in a row */
  92.     *vp++ = 0;            /* Mark end of envp[] */
  93.     assert(vp < argv+argc);    /* There is room, I swear there is */
  94.     assert(p1 < (char *)_start);    /* There's room here, too */
  95.     }
  96.     {
  97.     /*
  98.      * Next we'll load argv[].
  99.      * Beckemeyer uses ARGV=address_in_the_parent's_data_space
  100.      * to pass arguments which is
  101.      *    a) economical, since a Pexec() makes a copy in our format
  102.      *    b) sort of suicidal if the program you're running is buggy
  103.      * We just fetch the environment and put the value into argv[]
  104.      * above.  We fetch the ARGC=number_of_arguments parameter, too.
  105.      */
  106.     extern char *getenv();        /* To find the string */
  107.     extern long atol();        /* To convert the string */
  108.     register char *p;        /* To hold the value for a moment */
  109.  
  110.     if ((p = getenv("ARGV")) == 0)
  111.         return Cconws("cshtomwc: no ARGV found\n\r"), 1;
  112.     argv = (char **)atol(p);
  113.     if ((p = getenv("ARGC")) == 0)
  114.         return Cconws("cshtomwc: no ARGC found\n\r"), 1;
  115.     argc = (int)atol(p);
  116.     assert(((long)argv & 1) == 0);    /* Sorry Dave, just paranoid */
  117.     assert(argv+argc < (char **)BP->p_env);
  118.     assert(argv[argc] == 0);    /* I assume it's NULL terminated */
  119.     }
  120.     {
  121.     /*
  122.      * A temporary fix.  The PATH parsing routines will
  123.      * accept ';' as a separator in the next release.
  124.      * But for now, we need to translate ';' into ','.
  125.      */
  126.     extern char *getenv();
  127.     register char *p;
  128.     register int c;
  129.     if ((p = getenv("PATH")) != 0)
  130.         while (c = *p++)
  131.             if (c == ';')
  132.                 p[-1] = ',';
  133.     }
  134. #else
  135.     {
  136.     /*
  137.      * There is no environment in older cshell's
  138.      * so we simply plug the canned environment
  139.      * defined above.
  140.      */
  141.     envp = defenv;
  142.     }
  143. #endif
  144.     {
  145.     /*
  146.      * We need to fixup the _iovector which our libraries
  147.      * depend on for the information about file handles
  148.      * which gemdos is too dumb to provide.  Because the
  149.      * program we exec will see ARGV= in its environment
  150.      * it will assume that standard file handles 0, 1, and 2
  151.      * refer to standard input, standard output, and standard
  152.      * error streams respectively.  Beckemeyer doesn't provide
  153.      * any information about what he's done to these handles,
  154.      * but everyone complains that they can't redirect stderr
  155.      * so we'll assume that it points at aux:.
  156.      * We'll also assume that where ever stdout points
  157.      * it's all right to point stderr there as well.
  158.      * The only thing which will break our programs is a redirection
  159.      * of standard input to a file.  Without _iovector[0] == 'F',
  160.      * our programs cannot determine that stdin is not the console.
  161.      * Using Cconrs() to read a file is a loss, since it never
  162.      * returns EOF.  Using our io package to read a file when it thinks
  163.      * it's reading con: is a double loss, since we echo the missing
  164.      * linefeeds back to con:.
  165.      */
  166.     extern char *_iovector;
  167.     _iovector = "CCAP??????????????????????";    /* default setup */
  168.     dup2(dup(2), 4);    /* make copy of aux: */
  169.     dup2(dup(1), 2);    /* point stderr at stdout */
  170.     }
  171.    /*
  172.     * One last check.
  173.     */
  174.     if (argc < 2)
  175.     return Cconws("Usage: cshtomwc file_name [arg ...]\n\r"), 1;
  176.    /*
  177.     * And we're ready to go.
  178.     */
  179.     return execve(argv[1], argv+1, envp);
  180. }
  181.