home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / xmh / miscfuncs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-13  |  4.0 KB  |  171 lines

  1. /* $XConsortium: miscfuncs.c,v 1.6 91/07/13 17:52:59 gildea Exp $ */
  2.  
  3. #include <X11/Xos.h>
  4.  
  5. #ifndef X_NOT_POSIX
  6. #include <dirent.h>
  7. #else
  8. #ifdef SYSV
  9. #include <dirent.h>
  10. #else
  11. #ifdef USG
  12. #include <dirent.h>
  13. #else
  14. #include <sys/dir.h>
  15. #ifndef dirent
  16. #define dirent direct
  17. #endif
  18. #endif
  19. #endif
  20. #endif
  21.  
  22. char *malloc();
  23. char *realloc();
  24.  
  25.  
  26.  
  27. #if defined(SYSV) && (defined(SYSV386) || defined(MOTOROLA))
  28.  
  29. /* These systems don't have the ftruncate() system call, so we emulate it.
  30.  * This emulation can only shorten, not lengthen.
  31.  * For convenience, we pass in the name of the file, even though the
  32.  * real ftruncate doesn't.
  33.  */
  34.  
  35. #include <sys/types.h>
  36. #include <sys/stat.h>
  37. #include <fcntl.h>
  38. #include <stdio.h>
  39.  
  40. #define CHUNKSIZE 1024
  41.  
  42. int ftruncate_emu(fd, length, name)
  43.     int fd;
  44.     off_t length;
  45.     char *name;
  46. {
  47.     char            tmp_file[15];
  48.     int             new_fid, bytes_left, i;
  49.     unsigned char   buffer[CHUNKSIZE];
  50.     struct stat     stat_val;
  51.  
  52.     /* Open a temp file. */
  53.     sprintf(tmp_file, ".xmhtmp%d~", getpid());
  54.     (void) unlink(tmp_file);
  55.     new_fid = open(tmp_file, O_RDWR | O_CREAT);
  56.     lseek(fd, (off_t)0, 0);
  57.     
  58.     /* Copy original file to temp file. */
  59.     for (i = 0; i < length / CHUNKSIZE; i++) {
  60.     if (read(fd, buffer, CHUNKSIZE) != CHUNKSIZE) {
  61.         (void)fprintf(stderr, "xmh: read error in ftruncate emulation\n");
  62.         return -1;
  63.     }
  64.     else if (write(new_fid, buffer, CHUNKSIZE) != CHUNKSIZE) {
  65.         (void)fprintf(stderr, "xmh: write error in ftruncate emulation\n");
  66.         return -1;
  67.     }
  68.     }
  69.     bytes_left = length % CHUNKSIZE;
  70.     if (read(fd, buffer, bytes_left) != bytes_left) {
  71.     (void)fprintf(stderr, "xmh: read error in ftruncate() emulation\n");
  72.     return -1;
  73.     }
  74.     else if (write(new_fid, buffer, bytes_left) != bytes_left) {
  75.     (void)fprintf(stderr, "xmh: write error in ftruncate() emulation\n");
  76.     return -1;
  77.     }
  78.  
  79.     /* Set mode of temp file to that of original file. */
  80.     (void) fstat(fd, &stat_val);
  81.     (void) chmod(tmp_file, stat_val.st_mode);
  82.  
  83.     /* Close files, delete original, rename temp file to original. */
  84.     (void) myclose(new_fid);
  85.     (void) myclose(fd);
  86.     (void) unlink(name);    /* remove original */
  87.     (void) rename(tmp_file, name); /* rename temp file */
  88.  
  89.     /* If we weren't going to close the file right away in the one
  90.        place this is called from, we'd have to do something like this:
  91.     new_fid = myopen(name, O_RDWR, 0666);
  92.     if (new_fid != fd) {
  93.     dup2(new_fid, fd);
  94.     close(new_fid);
  95.     }
  96.        but the file does get closed, so we don't bother. */
  97.  
  98.     return 0;
  99. }
  100. #endif /* SYSV variant that needs ftruncate emulation */
  101.  
  102.  
  103. /*
  104. **  This code is by Rich Salz (rsalz@bbn.com), and ported to SVR4
  105. **  by David Elliott (dce@smsc.sony.com).  No copyrights were found
  106. **  in the original.  Subsequently modified by Bob Scheifler.
  107. */
  108.  
  109. /* A convenient shorthand. */
  110. typedef struct dirent     ENTRY;
  111.  
  112. /* Initial guess at directory size. */
  113. #define INITIAL_SIZE    20
  114.  
  115. static int StrCmp(a, b)
  116.     char **a, **b;
  117. {
  118.     return strcmp(*a, *b);
  119. }
  120.  
  121. int
  122. ScanDir(Name, List, Selector)
  123.     char          *Name;
  124.     char        ***List;
  125.     int             (*Selector)();
  126. {
  127.     register char     **names;
  128.     register ENTRY      *E;
  129.     register DIR      *Dp;
  130.     register int       i;
  131.     register int       size;
  132.  
  133.     /* Get initial list space and open directory. */
  134.     size = INITIAL_SIZE;
  135.     if (!(names = (char **)malloc(size * sizeof(char *))) ||
  136.     !(Dp = opendir(Name)))
  137.     return(-1);
  138.  
  139.     /* Read entries in the directory. */
  140.     for (i = 0; E = readdir(Dp); )
  141.     if (!Selector || (*Selector)(E->d_name)) {
  142.         /* User wants them all, or he wants this one. */
  143.         if (++i >= size) {
  144.         size <<= 1;
  145.         names = (char**)realloc((char *)names, size * sizeof(char*));
  146.         if (!names) {
  147.             closedir(Dp);
  148.             return(-1);
  149.         }
  150.         }
  151.  
  152.         /* Copy the entry. */
  153.         if (!(names[i - 1] = (char *)malloc(strlen(E->d_name) + 1))) {
  154.         closedir(Dp);
  155.         return(-1);
  156.         }
  157.         (void)strcpy(names[i - 1], E->d_name);
  158.     }
  159.  
  160.     /* Close things off. */
  161.     names[i] = (char *)0;
  162.     *List = names;
  163.     closedir(Dp);
  164.  
  165.     /* Sort? */
  166.     if (i)
  167.     qsort((char *)names, i, sizeof(char *), StrCmp);
  168.  
  169.     return(i);
  170. }
  171.