home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / uniflex.zip / ufdir.c < prev    next >
C/C++ Source or Header  |  1993-08-23  |  6KB  |  231 lines

  1. #include "ufk.h"
  2. #include <sys/dir.h>
  3. #include <modes.h>
  4. #include <stat.h>
  5.  
  6. /*
  7.  *  Get next file in a file group
  8.  */
  9.  
  10. get_file_spec(firsttime)
  11. char firsttime;
  12. {
  13.    char *wild_file_spec(),
  14.         *status;
  15.    static char my_firsttime;
  16.  
  17.    if (firsttime)
  18.    {
  19.       filenum = 1;                        /* First time initial values */
  20.       filecount = numprm - 1;
  21.       my_firsttime = TRUE;
  22.    }
  23.    do
  24.    {
  25.       if (rflg != 2)
  26.       {
  27.          status = wild_file_spec(params[filenum], my_firsttime);
  28.          my_firsttime = FALSE;
  29.       }
  30.       else
  31.       {
  32.          status = params[filenum++];      /* Don't parse for 'GET' */
  33.          if (filecount-- == 0)
  34.             break;
  35.       }
  36.       if (status == ERROR)
  37.       {
  38.          prterr(ER_DIROPN);
  39.          break;
  40.       }
  41.       else if (status)                    /* Got valid spec */
  42.       {
  43.          filnam = status;                 /* Setup pointer to spec */
  44.          return TRUE;
  45.       }
  46.       filenum++;                          /* Next parameter */
  47.       my_firsttime = TRUE;                /* Start new directory search */
  48.    }
  49.    while (--filecount > 0);               /* More to do */
  50.    return FALSE;                          /* done */
  51. }
  52.  
  53. char *wild_file_spec(mask,first)
  54. char mask[], first;
  55. {
  56.    static struct direct *ptr;
  57.    struct direct *diropen();
  58.    static char filename[128];
  59.    char status;
  60.  
  61.    if (first)
  62.       if ((ptr = diropen(mask)) == ERROR)
  63.          return (ERROR);                  /* Failed to open directory */
  64.    while(TRUE)
  65.    {
  66.       status = dirread(ptr,filename);
  67.       if (status == ERROR)                /* Check for end */
  68.          break;
  69.       if (status != TYPERROR)
  70.          if (mskcmp(filename,mask))       /* Check match if not a directory */
  71.             return(filename);             /* or device type file */
  72.    }
  73.    free(ptr);                             /* Release allocated memory */
  74.    return (FALSE);                        /* No more files */
  75. }
  76.  
  77. /*
  78. *** Compare against a mask
  79. *
  80. *  This function compares a given string against a mask and returns
  81. *  a 1 for 'compares' or a 0 for 'does not compare'.
  82. *
  83. *  A mask is a concatenation of the following elements:
  84. *
  85. *  c              literal character
  86. *  ?              any character match except endstring null
  87. *  [..]           character class (all of these characters)
  88. *  [^..]          negated character class (all but these characters)
  89. *  ^c             negated character (all but this character)
  90. *  *              zone (match zero or more occurences)
  91. *
  92. *  A character class consists of zero or more of the following
  93. *  surrounded by [ and ]:
  94. *
  95. *  c1-c2          range of ascii characters
  96. *  c1-c2..c1-c3   multiple ranges
  97. *
  98. */
  99.  
  100. mskcmp(string,m)
  101. char *string,*m;
  102. {
  103.    int k;
  104.    char *sp,*sav,string2[128];
  105.    char *n,msk[128];
  106.  
  107.    strcpy(sp = string2,string);
  108.    strcpy(n = msk,m);
  109.  
  110.    while (*n)
  111.    {
  112.       if (*n == '*')
  113.       {
  114.          sav = sp;
  115.          if (!*++n)
  116.             return (1);
  117.          while (*sp && !mskcmp(sp,n))
  118.             ++sp;
  119.          if (*sp)
  120.             continue;
  121.          sp = sav;
  122.       }
  123.       else
  124.          if (!(k = onecmp(*sp,n)))
  125.             return (0);
  126.          else
  127.             n += k;
  128.       if (*sp)
  129.          ++sp;
  130.    }
  131.    return (!*sp);
  132. }
  133.  
  134. /*
  135. *** Compare only one character (for mskcmp)
  136. */
  137.  
  138. onecmp(s,m)
  139. char s,*m;
  140. {
  141.    char c,setfind,setflag;
  142.    char *mp;
  143.  
  144.    if ((c = *(mp = m)) == '?' && s);         /* Okay as it is */
  145.    else if (c == '[')
  146.    {
  147.       setfind = setflag = 0;
  148.       if (*++mp == '^')
  149.       {
  150.          setflag = 1;
  151.          ++mp;
  152.       }
  153.       for (;(c = *mp) && c != ']'; ++mp)
  154.          if (*mp == '-' && s >= *(mp - 1) &&
  155.             s <= *(mp + 1) && *(mp - 1) <= *(mp + 1))
  156.          {
  157.             /* skip to trailing ']' */
  158.             while ((c = *(mp + 1)) && c != ']')
  159.                ++mp;
  160.             setfind = 1;
  161.          }
  162.          if (setfind == setflag)
  163.             return (0);
  164.          else
  165.             return (mp - m + 1);
  166.       }
  167.    else if (c == '^' && *(mp + 1) != s)
  168.       return (2);
  169.    else if (c != s)
  170.       return (0);
  171.  
  172.    return (1);
  173. }
  174.  
  175. /*
  176. *** Open disk directory
  177. */
  178.  
  179. int *dirptr;
  180. char dirspec[128];
  181.  
  182. struct direct *diropen(name)
  183. char *name;
  184. {
  185.    static struct direct ptr;
  186.    int i, j;
  187.  
  188.    for (i = strlen(name) - 1; i >= 0; --i)    /* Find filename */
  189.       if (name[i] == '/')
  190.          break;
  191.    for (j = 0; j <= i; j++)                   /* Save directory path */
  192.       dirspec[j] = name[j];
  193.    dirspec[j++] = '.';                        /* Append "." */
  194.    dirspec[j] = '\0';
  195.    if ((dirptr = open(dirspec,0)) == ERROR)   /* Open directory */
  196.       return (ERROR);
  197.    else
  198.       return (&ptr);
  199. }
  200.  
  201. dirread(ptr,filename)
  202. struct direct *ptr;
  203. char *filename;
  204. {
  205.    int i, j, status;
  206.    struct stat statptr;
  207.  
  208.    while (TRUE)
  209.    {
  210.       status = read(dirptr,ptr,sizeof(struct direct)); /* Get dir entry */
  211.       if (status == ERROR || status == NULL) /* Stop on EOF or error */
  212.          break;
  213.       if (ptr->d_ino)                        /* If not a deleted file */
  214.       {
  215.          strcpy(filename,dirspec);           /* Copy directory spec */
  216.          strncpy(&filename[strlen(filename)-1],ptr->d_name,DIRSIZ); /* +fnam */
  217.          stat(filename,&statptr);            /* Get file status */
  218.          statptr.st_mode &= S_IFMT;          /* Mask file type bits */
  219.          if ((statptr.st_mode == S_IFDIR) || /* Check if directory */
  220.              (statptr.st_mode == S_IFCHR) || /* or if character device */
  221.              (statptr.st_mode == S_IFBLK))   /* or if block device */
  222.             return(TYPERROR);
  223.          file_size = statptr.st_size;        /* Fill in file size */
  224.          transmit_chr_count = 0;             /* Start new sequence */
  225.          return (TRUE);
  226.       }
  227.    }
  228.    close(dirptr);
  229.    return (ERROR);
  230. }
  231.