home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / d / dshar116.zip / SETARGS.C < prev    next >
C/C++ Source or Header  |  1993-03-11  |  9KB  |  439 lines

  1.  /* setargs.c    dshar Ver1.16 nide@nara-wu.ac.jp */
  2. #define SETARGS_MAIN
  3.  
  4. #include <stdio.h>
  5. #include <ctype.h>
  6. #ifdef UNIX
  7. #  include <fcntl.h>
  8. #  include <sys/types.h>
  9. #  include <sys/stat.h>
  10. #endif
  11. #include <signal.h>
  12. #include "common.h"
  13.  
  14. #define RESPF    '@'
  15.  
  16. static    void    addarg(), addindarg(), addindfarg(), addfarg();
  17. static    void    adddirarg(), add1arg();
  18. static    char    *strsave(), *strpathcatsave(), *strdircatsave();
  19.  
  20. static    int    newac, newavsize;
  21. static    char    **newav;
  22.  
  23. char    *emalloc(p, i)
  24. register char    *p;
  25. register unsigned int    i;
  26. {
  27.     if(NULL == (p = (char *)(p == NULL ? malloc(i) : realloc(p, i))))
  28.         (perror(NULL), exit(1));
  29.     return p;
  30. }
  31.  
  32. void    setargs(acp, avp, passcnt)
  33. int    *acp, passcnt;
  34. char    **avp[];
  35. {
  36.     register int    ac = *acp;
  37.     register char    **av = *avp;
  38.  
  39.     newavsize = ac, newac = 0;
  40.     newav = (char **)emalloc(NULL, (newavsize + 1) * sizeof(char *));
  41.     ac--, add1arg(unixname(*av++));
  42.     while(passcnt-- && ac--) add1arg(*av++);
  43.     while(ac--) addarg(*av++);
  44.     newav[newac] = NULL;
  45.  
  46.     if(newavsize > newac) newav = (char **)
  47.             emalloc((char *)newav, (newac + 1) * sizeof(char *));
  48.     *acp = newac, *avp = newav;
  49. }
  50.  
  51. #ifdef UNIX
  52. FILE    *piperdopen(cmd, av, inf)
  53. register char    *cmd, **av;
  54. FILE    *inf;
  55. {
  56.     int    pipefd[2];
  57.  
  58.     if(-1 == pipe(pipefd)) (perror(NULL), exit(1));
  59.     fflush(stdout); /* must make output buffer empty */
  60.     switch(fork()){
  61.     case 0: /* child */
  62.         fclose(stdout);
  63.         if(inf == NULL){
  64.              /* stdin not yet closed... */
  65.             if(NULL == freopen("/dev/null", "r", stdin))
  66.                 (perror(NULL), exit(1));
  67.         } else { /* assuming inf != stdin */
  68.             fclose(stdin);
  69.             if(0 != dup(fileno(inf))) (perror(NULL), exit(1));
  70.             fclose(inf);
  71.         }
  72.         if(1 != dup(pipefd[1])) (perror(NULL), exit(1));
  73.         close(pipefd[0]), close(pipefd[1]);
  74.         execvp(cmd, av);
  75.          /* through to perror */
  76.     case -1:
  77.         perror(NULL), exit(1);
  78.     default:
  79.         if(inf != NULL) fclose(inf);
  80.         close(pipefd[1]);
  81.         return fdopen(pipefd[0], "r");
  82.     }
  83. }
  84.  
  85. static    isdir(name)
  86. register char    *name;
  87. {
  88.     struct    stat    statbuf;
  89.  
  90.     return(0 == stat(name, &statbuf) &&
  91.            S_IFDIR == (statbuf . st_mode & S_IFMT));
  92. }
  93.  
  94. static    FILE    *dirfindopen(s)
  95. register char    *s;
  96. {
  97.     static    char    *av[] = {
  98.         "find", NULL, "-type", "f", "-print", NULL
  99.     };
  100.  
  101.     av[1] = s;
  102.     return execrdopen(*av, av);
  103.      /* must call wait() afterward */
  104. }
  105. #endif /* UNIX */
  106.  
  107. static    isdirarg(s)
  108. register char    *s;
  109. {
  110.     for(; *s && s[1]; s++) if(iskanjipos(s)) s++;
  111.     return isDelim(*s);
  112. }
  113.  
  114. static    isdotdir(s)
  115. register char    *s;
  116. {
  117. #define isdotonlydir(s) \
  118.     (*(s) == '.' && (!*((s) + 1) || *((s) + 1) == '.' && !*((s) + 2)))
  119.  
  120.     if(isdotonlydir(s)) return 1;
  121.     for(; *s; s++){
  122.         if(iskanjipos(s)){
  123.             s++;
  124.             continue;
  125.         }
  126.         if(isDelim(*s) && isdotonlydir(s + 1)) return 1;
  127.     }
  128.     return 0;
  129. }
  130.  
  131. static    wropenchk(s)
  132. register char    *s;
  133. {
  134.     register FILE    *tmpf;
  135.     int    flag = 0;
  136.  
  137.     signal(SIGINT, SIG_IGN);
  138. #ifdef DEBUG
  139.     fprintf(stderr, "Test opening '%s'!\n", s);
  140. #endif
  141.     if(NULL != (tmpf = fopen(s, "r"))){
  142.         fclose(tmpf);
  143.         flag = 1;
  144.     } else
  145.     if(NULL != (tmpf = fopen(s, "w"))){
  146.         fclose(tmpf), unlink(s);
  147.         flag = 1;
  148.     }
  149.     signal(SIGINT, SIG_DFL);
  150.     return flag;
  151. }
  152.  
  153. is8bit(s)
  154. register char    *s;
  155. {
  156.     for(; *s; s++) if(!isascii(*s)) return 1;
  157.     return 0;
  158. }
  159.  
  160. have8bit(ac, av)
  161. register int    ac;
  162. register char    *av[];
  163. {
  164.     for(; ac; ac--, av++) if(is8bit(*av)) return 1;
  165.     return 0;
  166. }
  167.  
  168. isjapan() /* uses ShiftJIS? */
  169. {
  170. #ifndef UNIX
  171.     static    flag = -1;
  172.     register char    *tmpdir, *tmpname, *tmpbase = "_tmp$$\201\\.$$$";
  173.  
  174.     if(flag < 0){
  175.         flag = 0;
  176.         if(NULL != (tmpdir = getenv("TMP")) && !is8bit(tmpdir)){
  177.              /* if $TMP contains 8bit code, strpathcatsave()
  178.                 calls isjapan() recursively! */
  179.             tmpname = strpathcatsave(tmpdir, tmpbase);
  180.             if(wropenchk(tmpname)) flag = 1;
  181.             free(tmpname);
  182.         }
  183.         if(flag != 1 && wropenchk(tmpbase)) flag = 1;
  184.     }
  185.     return flag;
  186. #else
  187.     return 0; /* not supported */
  188. #endif
  189. }
  190.  
  191. iskanjipos(s)
  192. register char    *s;
  193. {
  194.     if(!iskanji(*s) || !isjapan()) return 0;
  195.     if(!s[1]){
  196.         fputs("Incomplete KANJI filename\n", stderr);
  197.         exit(1);
  198.     }
  199.     return 1;
  200. }
  201.  
  202. char    *nameconv(s, mode)
  203. register char    *s;
  204. register int    mode;
  205.  /* 0: MS-DOS -> UNIX, 1: UNIX -> MS-DOS.  Upper -> lower also.
  206.     Length is not changed. Overwrites the resulting string on each call */
  207. {
  208. #define MODEMAX 2
  209.     static    char    *p[MODEMAX] = {NULL, NULL};
  210.     static    int    psize[MODEMAX] = {0, 0};
  211.  
  212.     if(strlen(s) >= psize[mode])
  213.         p[mode] = emalloc(p[mode], (psize[mode] = strlen(s) + 1));
  214.     for(s = strcpy(p[mode], s); *s; s++){
  215.         if(iskanjipos(s)){
  216.             s++;
  217.             continue;
  218.         }
  219. #ifndef UNIX
  220.         if(is_upper(*s)) *s = tolower(*s); else
  221. #endif
  222.         switch(mode){
  223.         case 0:
  224.             if(*s == '\\') *s = '/';
  225.             break;
  226.         case 1:
  227.             if(*s == '/') *s = '\\';
  228.             break;
  229.         }
  230.     }
  231.     return p[mode];
  232. }
  233.  
  234. static    char    *strsave(s)
  235. register char    *s;
  236. {
  237.     return strcpy(emalloc(NULL, strlen(s) + 1), s);
  238. }
  239.  
  240. static    char    *strpathcatsave(s, r)
  241. register char    *s;
  242. char    *r;
  243. {
  244.     register char    *p;
  245.     int    notadd_delim;
  246.  
  247.     notadd_delim = !*s || isdirarg(s);
  248.     p = emalloc(NULL, strlen(s) + !notadd_delim + strlen(r) + 1);
  249.     return(sprintf(p, "%s%s%s", s, DELIM + notadd_delim, r), p);
  250. }
  251.  
  252. static    char    *strdircatsave(s, r)
  253. char    *s, *r;
  254. {
  255.     register char    *p, *end = NULL;
  256.  
  257.     for(p = s; *p && p[1]; p++){
  258.         if(iskanjipos(p)) p++;
  259.          else if(isDelim(*p)) end = p;
  260.     }
  261.     if(end++ == NULL){
  262.         return strsave(r);
  263.     } else {
  264.         p = emalloc(NULL, (end - s) + strlen(r) + 1);
  265.         return(strcpy(p + (end - s), r), strncpy(p, s, end - s));
  266.     }
  267. }
  268.  
  269. static    fnamecmp(x, y)
  270. char    **x, **y;
  271. {
  272. #define codemap(a) (isdrvmk(a) ? -257 : isdelim(a) ? -256 : a)
  273.  
  274.     register unsigned char    *p, *q;
  275.     int    a, b;
  276.  
  277.     for(p = (unsigned char *)*x, q = (unsigned char *)*y; ; p++, q++){
  278.         if(iskanjipos(p) || iskanjipos(q)){
  279.             if(*p != *q) return *p - *q;
  280.             if(p[1] != q[1])  return p[1] - q[1];
  281.             p++, q++;
  282.             continue;
  283.         }
  284.         a = *p, b = *q;
  285.         if(!a && !b) return 0;
  286.         a = codemap(a), b = codemap(b);
  287.         if(a != b) return a - b;
  288.     }
  289. }
  290.  
  291. static    void    addarg(s)
  292. register char    *s;
  293. {
  294.     register int    saveac = newac;
  295.  
  296.     if(*s == RESPF){
  297.         addindarg(++s);
  298.         if(saveac == newac){
  299.             fprintf(stderr,
  300.                 "No files found in response file %s\n",
  301.                 strcmp(s, "-") ? s : "<stdin>");
  302.              /* not exit */
  303.         }        
  304.     } else {
  305.         addfarg(s);
  306.         if(saveac != newac){
  307.             qsort((char *)&newav[saveac], newac - saveac,
  308.                         sizeof(char *),    fnamecmp);
  309.         } else {
  310.              /*
  311.             fprintf(stderr, "%s: File not found.\n", unixname(s));
  312.             exit(1);
  313.              */
  314. #ifndef UNIX
  315.             add1arg(s);
  316.              /* In case of using it as a plain string... */
  317. #endif
  318.         }
  319.     }
  320. }
  321.  
  322. static    void    addfarg(s)
  323. register char    *s;
  324. #ifdef UNIX
  325. {
  326.     register FILE    *dirfind;    
  327.     int    saveac = newac;
  328.  
  329.     if(isdir(s)){
  330.         if(NULL == (dirfind = dirfindopen(s))) (perror(s), exit(1));
  331.         addindfarg(dirfind);
  332.         fclose(dirfind);
  333.         wait(NULL);
  334.         if(saveac == newac){
  335.             fprintf(stderr,
  336.                     "No files found in directory %s\n", s);
  337.              /* not exit */
  338.         }    
  339.     } else {
  340.         add1arg(s);
  341.     }
  342. }
  343. #else
  344. {
  345.     struct    find_t    mydta;
  346.     register char    *tmppath;
  347.  
  348. #ifdef DEBUG
  349.     fprintf(stderr, "looking for '%s'...\n", s);
  350. #endif
  351.     if(isdotdir(s) || isdirarg(s)){
  352.         adddirarg(s);
  353.     } else if(0 == _dos_findfirst(dosname(s), 0x16, &mydta)){
  354.         do {
  355. #ifdef DEBUG
  356.             fprintf(stderr, "found '%s' in '%s'...\n",
  357.                             mydta . name, s);
  358. #endif
  359.             if(*mydta . name == '.') continue; /* '.', '..' */
  360.             tmppath = strdircatsave(s, mydta . name);
  361.             if(mydta . attrib & 0x10){
  362.                 adddirarg(tmppath);
  363.             } else {
  364.                 add1arg(unixname(tmppath));
  365.             }
  366.             free(tmppath);
  367.         } while(0 == _dos_findnext(&mydta));
  368.     }
  369. }
  370. #endif /* UNIX */
  371.  
  372. static    void    adddirarg(s)
  373. register char    *s;
  374. {
  375.     addfarg(s = strpathcatsave(s, "*.*"));
  376.     free(s);
  377. }
  378.  
  379. static    void    addindfarg(resf)
  380. register FILE    *resf;
  381. {
  382. #define MAXLEN    256
  383. #define MAXFMT    "%256s"
  384.  
  385.     char    name[MAXLEN + 1];
  386.     register int    c;
  387.  
  388.     while(1 == fscanf(resf, MAXFMT, name)){
  389.         if(c = getc(resf), !is_space(c)){
  390.             fprintf(stderr, "Too long name: %s%c...\n", name, c);
  391.             exit(1);
  392.         }
  393.         addarg(name);
  394.         if(c == EOF) break; /* else ungetc(c, resf); */
  395.     }
  396. }
  397.  
  398. static    void    addindarg(s)
  399. register char    *s;
  400. {
  401.     register FILE    *resf;
  402.  
  403.     if(!strcmp(s, "-")){
  404.         addindfarg(stdin);
  405.     } else {
  406.         if(NULL == (resf = fopen(s, "r"))){
  407.             perror(unixname(s)), exit(1);
  408.         }
  409.         addindfarg(resf);
  410.         fclose(resf);
  411.     }
  412. }
  413.  
  414. static    void    add1arg(s)
  415. register char    *s;
  416. {
  417.     while(newac >= newavsize){
  418.         newavsize += 20;
  419.         newav = (char **)emalloc((char *)newav,
  420.                     (newavsize + 1) * sizeof(char *));
  421.     }
  422. #ifdef DEBUG
  423.     fprintf(stderr, "allocated %d, saved into %d\n", newavsize, newac);
  424. #endif
  425.     newav[newac++] = strsave(s);
  426. }
  427.  
  428. #ifdef DEBUG
  429. main(ac, av)
  430. char    **av;
  431. {
  432.     int    i;
  433.  
  434.     setargs(&ac, &av, 0);
  435.     for(i = 0; i < ac; i++) printf("arg %d = %s\n", i, av[i]);
  436.     return 0;
  437. }
  438. #endif
  439.