1: #include "hd.h" 2: #include "mydir.h" 3: 4: #define curmtime wd_stb.st_mtime 5: 6: /* See dir.h for information about these variables */ 7: int tfiles, tpages, cpage, pageend; 8: 9: struct stat wd_stb; 10: 11: int wdfile; 12: char wdname [MPLEN + 1]; 13: 14: struct direct dirbuf [mfiles + 1]; 15: 16: char *d_namep [mfiles]; 17: 18: int dir_status; 19: struct stat scr_stb; 20: 21: char *dirmsg [] = { 22: "", "System Error", "Too big to Load", 23: "Executable but not Readable" 24: }; 25: 26: /* Enterdir -- Enter into new directory. 27: The parameter newdir is the file to change to. Pass a single 28: element file name or a full path name. "file", "..", or "." 29: are OK. "../..", "/a/b/..", "a/", or "a/." must be passed 30: to the file procedure instead. 31: 32: On success, there is a new current directory, and wdname has been 33: modified to reflect the new path name. ENTERDIR | REPLOT is the 34: return value. On failure, FAILURE is returned. Nothing is changed. 35: */ 36: 37: enterdir (newdir) char * newdir; { 38: 39: int entermode; /* Type of entry */ 40: #define FOREWARD 0 /* Deaper into dir */ 41: #define BACKWARD 1 /* Previous dir (..) */ 42: #define STOP 2 /* Stay in same place (.) */ 43: #define LOAD 3 /* Load new path name */ 44: 45: if (compe (newdir, DOT)) entermode = STOP; 46: else if (compe (newdir, DOTDOT)) entermode = BACKWARD; 47: else if (newdir[0] == '/') entermode = LOAD; 48: else entermode = FOREWARD; 49: 50: if (entermode == FOREWARD && strlen (wdname) > LPLEN) { 51: putmsg ("Cannot chdir -- Pathname too long"); 52: return FAILURE; 53: } 54: 55: if (chdir (newdir)) { 56: myperror (newdir); 57: return FAILURE; 58: } 59: 60: if (entermode == STOP); /* change to "." */ 61: else if (entermode == BACKWARDS) { /* change to ".." */ 62: todotdot (wdname); 63: if (ISROOT (wdname)) chdir (SLASH); 64: } 65: else if (entermode == LOAD) strcpy (wdname, newdir); 66: 67: else { 68: if (!ISROOT (wdname)) strcat (wdname, SLASH); 69: strcat (wdname, newdir); /* go deaper into dir */ 70: } 71: 72: close (wdfile); wdfile = open (DOT, 0); dir_status = unloaded; 73: cpage = 1; 74: return ENTERDIR | REPLOT; 75: } 76: 77: /* loaddir loads dir and sets assoc parameters */ 78: loaddir () { 79: 80: tpages = tfiles = 0; 81: if (wdfile < 0) {dir_status = protected; return;} 82: else dir_status = unloaded; 83: 84: fstat (wdfile, &wd_stb); 85: 86: if (wd_stb.st_size > max_dir_size) { 87: dir_status = toobig; return; 88: } 89: lseek (wdfile, 0L, 0); /* read in entire file */ 90: read (wdfile, dirbuf, (int) wd_stb.st_size); 91: 92: sortdir (); 93: 94: tpages = tfiles / nfpp + ((tfiles % nfpp) > 0); 95: dir_status = loaded; 96: return; 97: } 98: 99: /* sortdir sorts the directory entries. when done, the following is true: 100: 1) tfiles contains the number of files available 101: 2) the d_namep array will contain pointers to the files. 102: these will be sorted assending. 103: */ 104: sortdir () { 105: 106: struct direct *maxent, *dirp; 107: int dircmp (); 108: 109: tfiles = 0; 110: maxent = & dirbuf [wd_stb.st_size / dirsize]; 111: for (dirp = dirbuf; dirp < maxent; dirp++) { 112: if (dirp->d_ino) d_namep [tfiles++] = dirp->d_name; 113: dirp->d_ino = 0; 114: } 115: qsort (d_namep, tfiles, sizeof d_namep [0], dircmp); 116: } 117: 118: dircmp (a, b) char **a, **b; { 119: return strcmp (*a, *b); 120: } 121: 122: /* Dispdir displays a page of the directory. 123: W A R N I N G. Dispdir modifies global data. If the dir is not 124: loaded, or is out of date, dispdir will call on loaddir. 125: Cpage can be adjusted to conform to the current dir. 126: An out of date dir is reloaded only if reload is true. 127: 128: In general, the goal of dispdir is to make sure the internal 129: representation of the directory is consistent with the real 130: directory, and what is displayed is consistent with the internal 131: directory. 132: */ 133: 134: dispdir (reload) int reload; { 135: 136: int dirx; /* index into dirbuf */ 137: int dirchar; /* char to select file assoc. with dirx */ 138: 139: long lastmtime; /* last time dir was modified */ 140: 141: bufout (); clearmsg (-1); 142: if (reload) { 143: lastmtime = curmtime; 144: fstat (wdfile, &wd_stb); 145: if ((lastmtime != curmtime) || dir_status) loaddir (); 146: } 147: 148: cpage = max (1, min (cpage, tpages)); 149: pageend = 0; 150: 151: erase (); 152: printf ("Directory = %s %s", wdname, dirmsg [dir_status]); 153: 154: if (tfiles == 0) { 155: unbufout (); return; 156: } 157: 158: if (tpages > 1) { 159: at ((strlen (wdname) > 50) ? 268 : 168); 160: printf ("Page %d / %d ", cpage, tpages); 161: } 162: 163: pageend = tfiles % nfpp; 164: if (cpage != tpages || pageend == 0) pageend = nfpp; 165: 166: for (dirx = 0, dirchar = 'a'; dirx < pageend; dirx++, dirchar++) { 167: atfile (dirx, 3); 168: printf ("%c %s", dirchar, filename (dirx)); 169: } 170: unbufout (); 171: } 172: 173: /* Change dir to father of dir */ 174: todotdot (dir) char *dir; { 175: 176: register char *cp; 177: 178: for (cp = dir; *cp; cp++); /* Scan to end of name */ 179: while (*--cp != '/'); /* Scan back to a slash */ 180: if (cp == dir) cp++; /* Must handle root specially */ 181: *cp = 0; 182: }