home *** CD-ROM | disk | FTP | other *** search
/ Unix System Administration Handbook 1997 October / usah_oct97.iso / news / nn.tar / nn-6.5.1 / dir.c < prev    next >
C/C++ Source or Header  |  1995-04-29  |  4KB  |  204 lines

  1. /*
  2.  *    (c) Copyright 1990, Kim Fabricius Storm.  All rights reserved.
  3.  *
  4.  *    Directory access.
  5.  *     read file names in directory 'dir' starting with 'prefix'
  6.  */
  7.  
  8. #include "config.h"
  9. #include "articles.h"
  10. #include "dir.h"
  11.  
  12.  
  13. /* dir.c */
  14.  
  15. static sort_directory __APROTO((register char **f1, register char **f2));
  16.  
  17.  
  18. static char dir_path[FILENAME], *dir_tail;
  19.  
  20. #ifdef HAVE_DIRECTORY
  21.  
  22. static string_marker str_mark;
  23. static char **completions = NULL;
  24. static char **comp_iterator;
  25. static char **comp_help;
  26.  
  27. /*
  28.  * list_directory scans the directory twice; first time to find out how
  29.  * many matches there are, and second time to save the names, after
  30.  * sufficient memory have been allocated to store it all.
  31.  */
  32.  
  33. static int
  34. sort_directory(f1, f2)        /* Used by qsort */
  35.     register char **f1;
  36.     register char **f2;
  37. {
  38.     return strcmp(*f1, *f2);
  39. }
  40.  
  41. int
  42. list_directory(dir, prefix)
  43. char *dir, *prefix;
  44. {
  45.     DIR *dirp;
  46.     register Direntry *dp;
  47.     register char *cp;
  48.     register char **comp = NULL;
  49.     int pflen = strlen(prefix);
  50.     unsigned count = 0, comp_length = 0;
  51.  
  52.     if ((dirp = opendir(dir)) == NULL)
  53.     return 0;            /* tough luck */
  54.  
  55.     mark_str(&str_mark);
  56.  
  57.     while ((dp = readdir(dirp)) != NULL) {
  58.     cp = dp->d_name;
  59. #ifdef FAKED_DIRECTORY
  60.     if (dp->d_ino == 0) continue;
  61.     cp[14] = NUL;
  62. #endif
  63.     if (*cp == '.' && (cp[1] == '\0' || (cp[1] == '.' && cp[2] == '\0')))
  64.         continue;
  65.     if (pflen && strncmp(prefix, cp, pflen)) continue;
  66.     if (count == comp_length) {
  67.         comp_length += 100;
  68.         completions = resizeobj(completions, char *, comp_length + 1);
  69.         comp = completions + count;
  70.     }
  71.     strcpy(*comp++ = alloc_str(strlen(cp)), cp);
  72.     count++;
  73.     }
  74.     closedir(dirp);
  75.     if (count == 0) {
  76.     release_str(&str_mark);
  77.     return 0;
  78.     }
  79.  
  80.     quicksort(completions, count, char *, sort_directory);
  81.     *comp = (char *)0;
  82.     comp_iterator = completions;
  83.     comp_help = completions;
  84.  
  85.     dir_tail = dir_path;
  86.     while ((*dir_tail++ = *dir++));
  87.     dir_tail[-1] = '/';
  88.  
  89.     return 1;
  90. }
  91.  
  92. int
  93. next_directory(buffer, add_slash)
  94. register char *buffer;
  95. int add_slash;
  96. {
  97.     if (*comp_iterator != NULL) {
  98.     strcpy(buffer, *comp_iterator);
  99.  
  100.     if (add_slash) {
  101.         strcpy(dir_tail, *comp_iterator);
  102.         if (file_exist(dir_path, "d"))
  103.         strcat(buffer, "/");
  104.     }
  105.     comp_iterator++;
  106.     return 1;
  107.     }
  108.     close_directory();
  109.     return 0;
  110. }
  111.  
  112. int
  113. compl_help_directory()
  114. {
  115.     list_completion((char *)NULL);
  116.  
  117.     if (*comp_help == NULL) comp_help = completions;
  118.     while (*comp_help && list_completion(*comp_help))
  119.         comp_help++;
  120.  
  121.     fl;
  122.     return 1;
  123. }
  124.  
  125. void
  126. close_directory()
  127. {
  128.     if (completions) {
  129.     release_str(&str_mark);
  130.     freeobj(completions);
  131.     completions = NULL;
  132.     }
  133. }
  134.  
  135. #else
  136.  
  137. static FILE *dirf;
  138. static int prefix_lgt;
  139.  
  140. list_directory(dir, prefix)
  141. char *dir, *prefix;
  142. {
  143.     if (prefix[0])
  144.     sprintf(dir_path, "cd %s && echo %s* 2>/dev/null", dir, prefix);
  145.     else
  146.     sprintf(dir_path, "cd %s && ls 2>/dev/null", dir);
  147.     prefix_lgt = strlen(prefix);
  148.  
  149.     if ((dirf = popen(dir_path, "r")) == NULL) return 0;
  150.  
  151.     dir_tail = dir_path;
  152.     while (*dir_tail++ = *dir++);
  153.     dir_tail[-1] = '/';
  154.  
  155.     return 1;
  156. }
  157.  
  158. next_directory(buffer, add_slash)
  159. char *buffer;
  160. int add_slash;
  161. {
  162.     register char *cp;
  163.     register int c;
  164.  
  165.     cp = buffer;
  166.     while ((c = getc(dirf)) != EOF && (c != SP) && (c != NL))
  167.     *cp++ = c;
  168.  
  169.     if (cp != buffer) {
  170.     *cp = NUL;
  171.     if (strcmp(buffer + prefix_lgt, "*")) {
  172.  
  173.         if (!add_slash) return 1;
  174.  
  175.         strcpy(dir_tail, buffer);
  176.             if (file_exist(dir_path, "d")) {
  177.         *cp++ = '/';
  178.         *cp = NUL;
  179.         }
  180.  
  181.         return 1;
  182.     }
  183.  
  184.     }
  185.  
  186.     close_directory();
  187.     return 0;
  188. }
  189.  
  190. compl_help_directory()
  191. {
  192.     return 0;
  193. }
  194.  
  195. close_directory()
  196. {
  197.     if (dirf) {
  198.     pclose(dirf);
  199.     dirf = NULL;
  200.     }
  201. }
  202. #endif /* HAVE_DIRECTORY */
  203.  
  204.