home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / lib / util / gwdir.2.9.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-02-01  |  4.1 KB  |  145 lines

  1. #include "util.h"
  2. #include "conf.h"
  3. #include <sys/stat.h>
  4.  
  5. struct  kb_dir  {
  6.     short   kd_ino;
  7.     char    kd_name[14];
  8. };
  9.  
  10. LOCVAR char wd_DOT[] = ".";
  11. LOCVAR char wd_DOTDOT[] = "..";
  12. LOCVAR char wd_read[] = "r";
  13.  
  14. LOCVAR char     wkd_name[128];     /* max size of path string            */
  15. LOCVAR jmp_buf  wd_retloc;
  16. LOCVAR union wd                 /* unioned for making i/o cleaner       */
  17. {
  18.     char            io[sizeof (struct kb_dir)];
  19.     struct kb_dir   dir;
  20. } wd_entry;
  21. LOCVAR  char    dummy;  /* will be null - kludge to stop 14 char filenames */
  22.             /* breaking this routine */
  23.  
  24. LOCVAR FILE * wd_fp;
  25.  
  26. char *
  27.     gwdir ()                    /* what is current working directory? */
  28. {
  29.     struct stat wd_stat;
  30.     short     lastkd_ino;            /* last inode num                     */
  31.     char    buf[BUFSIZ];
  32.  
  33.     if (!setjmp (wd_retloc))
  34.     {                             /* end due to eof or err              */
  35.     if(wd_fp != (FILE *)EOF && wd_fp != NULL)
  36.         setbuf (wd_fp, NULL);
  37.     if (wd_fp == (FILE *) EOF || wd_fp == (FILE *) NULL ||
  38.         fclose (wd_fp) == EOF ||
  39.         wkd_name[0] == '\0' ||
  40.         chdir (wkd_name) < OK)
  41.         return ((char *) NOTOK);
  42.  
  43.     return (wkd_name);
  44.     }
  45.  
  46.     wkd_name[0] = '\0';
  47.     lastkd_ino = -1;              /* force to be set on first pass      */
  48.  
  49.     if (stat (wd_DOT, &wd_stat) < 0 ||         /* get inode num for this dir     */
  50.         (wd_fp = fopen (wd_DOTDOT, wd_read)) == NULL)
  51.     longjmp (wd_retloc, TRUE);
  52.                   /* set to compare DOTDOT inodes       */
  53.     setbuf (wd_fp, buf);
  54.  
  55.     for (;;)
  56.     {
  57.     for (;;)
  58.     {                         /* cycle thru dir's inodes            */
  59.         fread (wd_entry.io, sizeof (struct kb_dir), 1, wd_fp);
  60.         if (ferror (wd_fp) || feof (wd_fp))
  61.         longjmp (wd_retloc, TRUE);
  62.  
  63.         if (wd_entry.dir.kd_ino == wd_stat.st_ino)
  64.         break;            /* got a match                        */
  65.     }
  66.     if (wd_fp == (FILE *) EOF || wd_fp == (FILE *) NULL ||
  67.          fclose (wd_fp) == EOF || ferror (wd_fp) || feof (wd_fp))
  68.         longjmp (wd_retloc, TRUE);
  69.     if (wd_entry.dir.kd_ino == 1)  /* hit the root directory             */
  70.         wd_ckroot ();         /* try to find its name               */
  71.  
  72.     if (wd_entry.dir.kd_ino == lastkd_ino)
  73.                   /* we are cycling at top              */
  74.         longjmp (wd_retloc, TRUE);
  75.     else                      /* remember for next level up         */
  76.         lastkd_ino = wd_entry.dir.kd_ino;
  77.  
  78.     wd_cat ();                /* add current name to end            */
  79.  
  80.     if (chdir (wd_DOTDOT) < OK || /* set up for next pass this dir      */
  81.            stat (wd_DOT, &wd_stat) < OK ||
  82.            freopen (wd_DOTDOT, wd_read, wd_fp) == NULL)
  83.         longjmp (wd_retloc, TRUE);
  84.     }
  85. }
  86.  
  87. LOCFUN wd_ckroot ()               /* check root dir for filesys name    */
  88. {
  89.     static char wd_root[] = "/";
  90.     struct stat wd_stat,
  91.         owd_stat;         /* to save device info                */
  92.  
  93.     if (stat (wd_entry.dir.kd_name, &wd_stat) < 0)
  94.     longjmp (wd_retloc, TRUE);
  95.  
  96.     owd_stat.st_dev = wd_stat.st_dev;
  97.  
  98.     if (chdir (wd_root) < OK)
  99.     longjmp (wd_retloc, TRUE);
  100.  
  101.     if (freopen (wd_root, wd_read, wd_fp) == NULL)
  102.     longjmp (wd_retloc, TRUE);
  103.  
  104.     for (;;)
  105.     {                             /* read thru "/" dir                  */
  106.     fread (wd_entry.io, sizeof (struct kb_dir), 1, wd_fp);
  107.     if (ferror (wd_fp) || feof (wd_fp))
  108.         longjmp (wd_retloc, TRUE);
  109.  
  110.     if (wd_entry.dir.kd_ino == 0)  /* not allocated                      */
  111.         continue;
  112.  
  113.     if (stat (wd_entry.dir.kd_name, &wd_stat) < 0)
  114.         longjmp (wd_retloc, TRUE);
  115.  
  116.     if (wd_stat.st_dev == owd_stat.st_dev)
  117.     {                         /* device types match                 */
  118.         wd_stat.st_mode &= S_IFMT;
  119.         if (wd_stat.st_mode == S_IFDIR)
  120.         break;            /* and it is a directory              */
  121.     }
  122.     }
  123.     if (strcmp (wd_entry.dir.kd_name, wd_DOT) != 0 &&
  124.         strcmp (wd_entry.dir.kd_name, wd_DOTDOT) != 0)
  125.     wd_cat ();                /* it has a real text name, too       */
  126.  
  127.     wd_entry.dir.kd_name[0] = '\0';    /* hack, to force "/" at front        */
  128.     wd_cat ();
  129.     longjmp (wd_retloc, TRUE);
  130. }
  131.  
  132. LOCFUN wd_cat ()
  133. {
  134.     extern char *strcpy (),
  135.         *strcat ();
  136.  
  137.     if (wkd_name[0] == 0)
  138.     strcpy (wkd_name, wd_entry.dir.kd_name);
  139.     else
  140.     {
  141.     strcat (wkd_name, "/");
  142.     strcat (wkd_name, wd_entry.dir.kd_name);
  143.     }
  144. }
  145.