home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / GLOB.C < prev    next >
C/C++ Source or Header  |  1994-04-17  |  6KB  |  201 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <dirent.h>
  5. #include <time.h>
  6. #include <sys/stat.h>
  7.   
  8. #define GLOB_INTERNAL
  9. #include "dirutil.h"
  10.   
  11. /*
  12.  * Second approximation of glob routine for JNOS/Linux
  13.  */
  14.   
  15. static int ff1(char *, char *, char *, struct ffblk *, int);
  16.   
  17. static char *
  18. __ff_cat(char *pfx, char *sfx)
  19. {
  20.     static char buf[1024];
  21.   
  22.     buf[0] = '\0';
  23.     if (pfx && *pfx)
  24.         strcat(buf, pfx);
  25.     if (pfx && *pfx && sfx && *sfx && (*pfx != '/' || pfx[1] != '\0'))
  26.         strcat(buf, "/");
  27.     if (sfx && *sfx)
  28.         strcat(buf, sfx);
  29.     return buf;
  30. }
  31.   
  32. int
  33. findnext(struct ffblk *ff)
  34. {
  35.     struct stat sb;
  36.     char *path;
  37.     int rc, m;
  38.   
  39.     /* special-case literal: if there's no pattern, just close the ff */
  40.     if (!ff->ff_pat)
  41.         return -1;
  42.     for (;;)
  43.     {
  44.         while ((ff->ff_cur = readdir(ff->ff_dir)) &&
  45.             !wildmat(ff->ff_cur->d_name, ff->ff_pat, 0))
  46.             ;
  47.         if (!ff->ff_cur)
  48.         {
  49.             closedir(ff->ff_dir);
  50.             j_free(ff->ff_pat);
  51.             j_free(ff->ff_pfx);
  52.             return -1;
  53.         }
  54.         path = strdup(__ff_cat(ff->ff_pfx, ff->ff_cur->d_name));
  55.         if ((*ff->ff_cur->d_name == '.' && !(ff->ff_sattr & FA_HIDDEN)) ||
  56.             stat(path, &sb) == -1 ||
  57.             (!(ff->ff_sattr & FA_DIREC) && S_ISDIR(sb.st_mode)) ||
  58.             (!S_ISREG(sb.st_mode) && !(ff->ff_sattr & FA_SYSTEM) &&
  59.             !(ff->ff_sattr & FA_HIDDEN)))
  60.         {
  61.             j_free(path);
  62.             continue;
  63.         }
  64.         j_free(path);
  65.         if (geteuid() == sb.st_uid)
  66.             m = 0700;
  67.         else if (getegid() == sb.st_gid)
  68.             m = 0070;
  69.         else
  70.             m = 0007;
  71.         if (!(sb.st_mode & m) && !(ff->ff_sattr & FA_SYSTEM))
  72.             continue;
  73.         ff->ff_ftime = *localtime(&sb.st_mtime);
  74.         ff->ff_fsize = sb.st_size;
  75.         if (S_ISDIR(sb.st_mode))
  76.             ff->ff_attrib = FA_DIREC;
  77.         else if (!S_ISREG(sb.st_mode) || !(sb.st_mode & m))
  78.             ff->ff_attrib = FA_SYSTEM | FA_HIDDEN;
  79.         else
  80.             ff->ff_attrib = FA_NORMAL;
  81.         if (*ff->ff_cur->d_name == '.')
  82.             ff->ff_attrib |= FA_HIDDEN;
  83.         if (!(sb.st_mode & m & 0222))
  84.             ff->ff_attrib |= FA_RDONLY;
  85.         strcpy(ff->ff_name, ff->ff_cur->d_name);
  86.         return 0;
  87.     }
  88. }
  89.   
  90. static int
  91. ff1(char *prefix, char *dir, char *pat, struct ffblk *ff, int attr)
  92. {
  93.     char *pp, *cp, *ep, *xp, *bp;
  94.     struct stat sb;
  95.     int m;
  96.   
  97.     ff->ff_pfx = strdup(__ff_cat(prefix, dir));
  98.     ff->ff_pat = 0;
  99.     ff->ff_dir = 0;
  100.     ff->ff_cur = 0;
  101.     ff->ff_name[0] = '\0';
  102.     ff->ff_sattr = attr;
  103.     cp = ep = pp = strdup(pat);
  104.     xp = 0;
  105.     bp = "";
  106.     for (; *cp; cp = ep)
  107.     {
  108.         while (*ep && *ep != '/') /* extract next component */
  109.         {
  110.             if (*ep == '?' || *ep == '*' || *ep == '[')
  111.                 xp = ep;    /* record presence of wildcard characters */
  112.             ep++;
  113.         }
  114.         if (*ep)
  115.             *ep++ = '\0';
  116.         if (xp)         /* if we got a wildcard, abort */
  117.             break;
  118.         if (!*cp || strcmp(cp, ".") == 0) /* prune null components */
  119.             continue;
  120.         xp = ff->ff_pfx;    /* append component to prefix */
  121.         ff->ff_pfx = strdup(__ff_cat(xp, cp));
  122.         j_free(xp);
  123.         xp = 0;
  124.         bp = cp;
  125.     }
  126.     if (!xp)            /* no wildcards; just return it */
  127.     {
  128.         strcpy(ff->ff_name, bp);
  129.         if ((*bp == '.' && !(attr & FA_HIDDEN)) ||
  130.             stat(ff->ff_pfx, &sb) == -1 ||
  131.             (!(attr & FA_DIREC) && S_ISDIR(sb.st_mode)) ||
  132.             (!S_ISREG(sb.st_mode) && !(attr & FA_SYSTEM) &&
  133.             !(attr & FA_HIDDEN)))
  134.         {
  135.             j_free(pp);
  136.             j_free(ff->ff_pfx);
  137.             return -1;
  138.         }
  139.     /* unreadable files are system files */
  140.     /* don't check for root:  if you run nos as root you're dead anyway */
  141.         if (geteuid() == sb.st_uid)
  142.             m = 0700;
  143.         else if (getegid() == sb.st_gid) /* WARNING: ignores group vec */
  144.             m = 0070;
  145.         else
  146.             m = 0007;
  147.         if (!(attr & FA_SYSTEM) && !(sb.st_mode & m))
  148.         {
  149.             j_free(ff->ff_pfx);
  150.             j_free(pp);
  151.             return -1;
  152.         }
  153.         ff->ff_ftime = *localtime(&sb.st_mtime);
  154.         ff->ff_fsize = sb.st_size;
  155.         if (S_ISDIR(sb.st_mode))
  156.             ff->ff_attrib = FA_DIREC;
  157.         else if (!S_ISREG(sb.st_mode) || !(sb.st_mode & m))
  158.             ff->ff_attrib = FA_SYSTEM | FA_HIDDEN;
  159.         else
  160.             ff->ff_attrib = FA_NORMAL;
  161.         if (*bp == '.')
  162.             ff->ff_attrib |= FA_HIDDEN;
  163.         if (!(sb.st_mode & m & 0222))
  164.             ff->ff_attrib |= FA_RDONLY;
  165.         j_free(pp);
  166.         j_free(ff->ff_pfx);
  167.         ff->ff_pfx = 0;
  168.         return 0;
  169.     }
  170.     if (*ep)            /* no subdirs this version */
  171.     {
  172.         j_free(ff->ff_pfx);
  173.         j_free(pp);
  174.         return -1;
  175.     }
  176.     ff->ff_pat = strdup(cp);    /* the wildcarded component */
  177.     j_free(pp);
  178.     if (!(ff->ff_dir = opendir(*ff->ff_pfx? ff->ff_pfx: ".")))
  179.     {
  180.         j_free(ff->ff_pat);
  181.         j_free(ff->ff_pfx);
  182.         return -1;
  183.     }
  184.     return findnext(ff);
  185. }
  186.   
  187. int
  188. findfirst(char *pat, struct ffblk *ff, int attr)
  189. {
  190.     return ff1((*pat == '/'? "/": ""), "", (*pat == '/'? pat + 1: pat),
  191.     ff, attr);
  192. }
  193.   
  194. void
  195. findlast(struct ffblk *ff)
  196. {
  197.     closedir(ff->ff_dir);
  198.     j_free(ff->ff_pat);
  199.     j_free(ff->ff_pfx);
  200. }
  201.