home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-386-Vol-2of3.iso / c / csh4.zip / _CROOT.C next >
C/C++ Source or Header  |  1985-09-05  |  5KB  |  245 lines

  1. /* Copyright (C) 1981,1982, 1983 by Manx Software Systems */
  2. #include <stdio.h>
  3. #include <errno.h>
  4. #include <fcntl.h>
  5. #ifndef NULL
  6. #define NULL ((void *)0)
  7. #endif
  8.  
  9. char *get_first(), *get_next(), *sbrk();
  10. char *wilderr = "No wild cards in command names!!\r\n";
  11. #define ARGMAX 256
  12. static char *Argv[ARGMAX];
  13. static int Argc;
  14. static char curr_path[128];
  15.  
  16. _Croot(cp,cmd)
  17. register char *cp;
  18. int (*cmd)();
  19. {
  20.     int returnval = 0,isls = 0;
  21.     char *startbuf,*endbuf;
  22.     register char *cp2;
  23.     char *wild_match;
  24.     char *index(),*rindex(), *save_str();
  25.     char *path,*copy; int j;
  26.     char *quote;
  27.     int k,omode; char *fname;
  28.     int in = -1, out = -1;
  29.     /* lets try not to free things not allocated by malloc */
  30.     startbuf = cp; endbuf = &cp[strlen(cp)];
  31.     /* ls is a special case !!! */
  32.     isls = 0 == strncmp(cp,"ls",2);
  33.     /* loop through arguments */
  34.     for (Argc = 0;;) 
  35.     {
  36.         /* skip blanks */
  37.         while (*cp == ' ' || *cp == '\t')
  38.             ++cp;
  39.  
  40.         /* if you're at the end of command line, you're done */
  41.         if (*cp == 0)
  42.             break;
  43.         /* handle redirection . . . */
  44.         if (*cp == '>')
  45.         {
  46.             k = 1;
  47.             if (cp[1] == '>')
  48.             {
  49.                 ++cp;
  50.                 omode = O_CREAT | O_WRONLY | O_APPEND; 
  51.             }
  52.             else
  53.                 omode = O_CREAT | O_WRONLY | O_TRUNC;
  54.             goto redirect;
  55.         } else if (*cp == '<')
  56.         {
  57.             k = 0;
  58.     redirect:
  59.             while (*++cp == ' ' || *cp == '\t')
  60.                 ;
  61.             fname = cp;
  62.             while(*++cp)
  63.                 if (*cp == ' ' || *cp == '\t')
  64.                 {
  65.                     *cp++ = 0;
  66.                     break;
  67.                 }
  68.             close(k);
  69.             if (k)
  70.                 out = k = open(fname,omode);
  71.             else
  72.                 in = k = open(fname,O_RDONLY);
  73.             if (k == -1)
  74.             {
  75.                 perror("redirection");
  76.                 return -1;
  77.             }
  78.             /* go back for next argument */
  79.             continue;
  80.         }
  81.         /* find beginning of next argument */
  82.         cp2 = cp;    /* save original pointer to the string */
  83.         while (*++cp2)
  84.         {
  85.             /* if you hit a space char - stick a null in to terminate last
  86.                argument
  87.              */
  88.             if (*cp2 == ' ' || *cp2 == '\t') 
  89.             {
  90.                 *cp2++ = 0;
  91.                 break;
  92.             }
  93.         }
  94.  
  95.         /* if no wild card characters, do it the old fashioned way */
  96.         if (index(cp,'*') == NULL && index(cp,'?') == NULL)
  97.         {
  98. notranslate:
  99.             if (*cp == '\'')
  100.             /* pass through untranslated, with quotes stripped */
  101.             {
  102.                 cp++;    /* point past quote */
  103.                 if ( NULL == (quote = rindex(cp,'\'')))
  104.                 {
  105.                     write(2,"sh - no close quotes on command line\r\n",38);
  106.                     goto free_args;
  107.                 }
  108.                 *quote = '\0';
  109.             }
  110.             /* update the next argv pointer */
  111.             Argv[Argc] = cp;
  112.             /* bump the argument count */
  113.             if (++Argc == ARGMAX)
  114.                 abort();
  115.         }
  116.         else
  117.         {
  118.             if (*cp == '"' || *cp == '\'')
  119.                 goto notranslate;
  120.             if (isls)
  121.                 goto notranslate;
  122.             /* wild cards not permitted on first run thru */
  123.             if (Argc == 0)
  124.             {
  125.                 write(2,wilderr,strlen(wilderr));
  126.                 return -1;
  127.             }
  128.             /* if there is a path included, save it off */
  129.             if ((path = rindex(cp,'\\')) || (path = rindex(cp,'/')))
  130.             {
  131.                 copy = cp;
  132.                 /* copy to curr_path, mapping / to \ */
  133.                 for (j = 0; j < sizeof(curr_path) && copy != path+1; copy++,j++)
  134.                     curr_path[j] = (*copy == '/' ? '\\' : *copy);
  135.                 /* terminate string */
  136.                 curr_path[j] = '\0';
  137.             }
  138.             else if (cp[1] == ':')
  139.             {
  140.                 copy = cp;
  141.                 for (j = 0; j < 2; j++)
  142.                     curr_path[j] = *copy++;
  143.                 curr_path[j] = '\0';
  144.             } else
  145.             /* null path */
  146.                 curr_path[0] = 0;
  147.             if (wild_match = get_first(cp))
  148.             {
  149.                 /* update the next argv pointer */
  150.                 Argv[Argc]= save_str(wild_match);
  151.                 /* bump the argument count */
  152.                 if (++Argc == ARGMAX)
  153.                     abort();
  154.                 /* get the rest of the matching file names */
  155.                 while (wild_match = get_next())
  156.                 {
  157.                     
  158.                     /* update the next argv pointer */
  159.                     Argv[Argc] = save_str(wild_match);
  160.                     /* bump the argument count */
  161.                     if (++Argc == ARGMAX)
  162.                         abort();
  163.                 }
  164.             }
  165.         }
  166.         cp = cp2;    /* point to beginning of next argument */
  167.     }
  168.     Argv[Argc] = NULL;    
  169.     returnval=(*cmd)(Argc,Argv);
  170.     if (in != -1)
  171.         close(in);
  172.     if (out != -1)
  173.         close(out);
  174.     /* free anything not dynamically allocated */
  175. free_args:
  176.     if (!isls)
  177.     {
  178.         for(j = 1;j < Argc; j++)
  179.             if (
  180.             !(Argv[j] >= startbuf && Argv[j] <= endbuf)    /* not in cmd line */
  181.             && Argv[j]                                    /* Not NULL            */
  182.                    )
  183.             free(Argv[j]);
  184.     }
  185.     return returnval;
  186. }
  187.  
  188. char *
  189. save_str(s)
  190.     register char *s;
  191. {
  192.     register char *r,*malloc();
  193.     int pathlen;
  194.     /* squirrel away matched file name */
  195.     if (NULL == (r = malloc(strlen(s)+(pathlen = strlen(curr_path))+1)))
  196.         abort();
  197.     strcat(curr_path,s);
  198.     strcpy(r,curr_path);
  199.     curr_path[pathlen] = '\0';
  200.     return r;
  201. }
  202.  
  203. abort()
  204. {
  205.     write(2, "Too many args.", 14);
  206.     _exit(200);
  207. }
  208.  
  209.  
  210. typedef struct
  211. {
  212.     char dos_reserved[21];
  213.     char attribute;
  214.     unsigned file_time;
  215.     unsigned file_date;
  216.     long file_size;
  217.     char file_name[13];
  218. } fcb;
  219. fcb wildcard;
  220.  
  221. char *get_first(fname)
  222.     char *fname;
  223. {
  224.     register int result;
  225.     /* set the disk transfer address */
  226.     bdos(0x1A,&wildcard);
  227.     result = bdos(0x4E,fname,0);
  228.     /* make the find first call */
  229.     if(2 == result || 18 == result)
  230.         return NULL;
  231.     return &(wildcard.file_name[0]);
  232. }
  233.  
  234. char *get_next()
  235. {
  236.     register int result;
  237.     /* set the disk transfer address */
  238.     bdos(0x1A,&wildcard);
  239.     result = bdos(0x4f,0,0);
  240.     /* make the find next call */
  241.     if (18 == result)
  242.         return NULL;
  243.     return &(wildcard.file_name[0]);
  244. }
  245.