home *** CD-ROM | disk | FTP | other *** search
- /*
- * public domain implementation of the BSD UNIX(c) `ls' routine.
- *
- * written by Kevin Sweet. entered into the public domain 1988.
- *
- * compile with: tcc -ms -f- -Z -O -G -k -N ls
- *
- */
-
- #include <alloc.h>
- #include <ctype.h>
- #include <dir.h>
- #include <dos.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <time.h>
- #define FA_EXEC 0x40
-
- #define DOT_AL /* if defined, the entries '.' and '..' are
- * only displayed when both the 'a' and the 'l'
- * options are selected */
- #define SIZE_CL /* display file size in clusters rather than
- * "kilobytes" */
-
- struct datum {
- int attrib;
- long sizeb;
- time_t date;
- char pname[MAXPATH];
- };
- #define fname(a) (strrchr((a)->pname, '\\')+1)
- #ifdef SIZE_CL
- #define sizek(a) (((a)->sizeb+cluster_size-1)/cluster_size)
- #else
- #define sizek(a) (((a)->sizeb+1023L)/1024L)
- #endif
-
- struct flags {
- short f_all;
- short f_column;
- short f_directory;
- short f_long;
- short f_kilobyte;
- short f_nosort;
- short f_pwd;
- short f_recursive;
- short f_type;
- short f_zoo;
- short s_reverse;
- short s_size;
- short s_time;
- };
-
- extern char *main_cwd;
- extern int main_dev;
- extern int main_year;
- #ifdef SIZE_CL
- extern long cluster_size;
- #endif
- extern short FA_FILES;
- extern unsigned onceover;
- extern struct flags flags;
-
- int ls(int argc, char **argv);
-
- int parse_file(char *path, char *d, char *p, char *f, char *e);
- #define getwd() getcwd((char *) NULL, MAXPATH*sizeof(char))
-
- char *main_cwd;
- int main_dev;
- int main_year;
- short FA_FILES;
- unsigned onceover;
- struct flags flags;
-
- static int break_func(void);
- static int getarg(char c, char off);
- static void gethelp();
-
- #define new_entry(a,e) { \
- *((a)) = (char *) malloc((strlen((e))+1)*sizeof(char)); \
- strcpy(*(((a)++)), (e)); \
- }
- #define last_entry(c,a) if ((c)) { \
- *((a)) = (char *) NULL; \
- (a) -= (c); \
- }
- #define alloc_error() { \
- fprintf(stderr, "insufficient memory"); \
- exit(1); \
- }
-
- main(int argc, char **argv)
- {
- int nfiles;
- char **files;
- int ndirs;
- char **dirs;
- char *cp;
- long ltime;
- char d[MAXDRIVE], p[MAXDIR], f[MAXFILE], e[MAXEXT];
- char arg[MAXPATH], path[MAXPATH];
- int i, wild;
- struct ffblk ffblk;
-
- main_cwd = getwd();
- main_dev = getdisk();
- ctrlbrk(break_func);
-
- time(<ime);
- daylight = 0; /* account for daylight savings time */
- main_year = atoi(asctime(localtime(<ime))+20);
-
- onceover = 0;
- FA_FILES = FA_DIREC;
- flags.f_all = 0;
- flags.f_column = 1;
- flags.f_long = 0;
- flags.f_kilobyte = 0;
- flags.f_nosort = 0;
- flags.f_pwd = 0;
- flags.f_recursive = 0;
- flags.f_type = 0;
- flags.f_zoo = 0;
- flags.s_reverse = 0;
- flags.s_size = 0;
- flags.s_time = 0;
-
- /* find options
- * since the selected files will depend on flags.f_directory
- */
- for (cp = getenv("LS"); *cp; ++cp) getarg(*cp, *(cp+1));
-
- for (++argv; *argv; ++argv)
- switch (**argv) {
- case '-':
- for (cp = *argv, ++cp; *cp; ++cp)
- if (getarg(*cp, *(cp+1)))
- exit(0);
- break;
- default:
- }
- argv -= argc;
-
- /* find the number of selected files
- * find the number first for space saving
- */
- ndirs = nfiles = 0;
- for (++argv; *argv; ++argv)
- switch (**argv) {
- case '-':
- break;
- default:
- parse_file(*argv, d, p, f, e);
- sprintf(arg, "%s%s%s%s", d, p, f, e);
- wild = findfirst(arg, &ffblk,
- FA_DIREC | FA_HIDDEN | FA_SYSTEM);
- if (wild) {
- nfiles++;
- continue;
- }
- while (!wild) {
- if (flags.f_directory) {
- nfiles++;
- } else if (ffblk.ff_attrib & FA_DIREC) {
- if (*ffblk.ff_name != '.')
- ndirs++;
- } else {
- nfiles++;
- }
- wild = findnext(&ffblk);
- }
- }
- argv -= argc;
-
- if (!nfiles && !ndirs) {
- ndirs = 1;
- dirs = (char **) calloc(2, sizeof(char *));
- if (!dirs) alloc_error();
- getcwd(path, MAXPATH*sizeof(char));
- if (path[3]) strcat(path, "\\.");
- *dirs = path;
- *(dirs+1) = (char *) NULL;
- } else {
- if (nfiles) {
- files = (char **) calloc((nfiles+1),
- sizeof(char *));
- if (!files) alloc_error();
- }
- if (ndirs) {
- dirs = (char **) calloc((ndirs+1),
- sizeof(char *));
- if (!dirs) alloc_error();
- }
-
- /* save the selected files
- */
- for (++argv; *argv; ++argv) switch (**argv) {
- case '-':
- break;
- default:
- parse_file(*argv, d, p, f, e);
- sprintf(arg, "%s%s%s%s", d, p, f, e);
- wild = findfirst(arg, &ffblk,
- FA_DIREC | FA_HIDDEN | FA_SYSTEM);
- if (wild) {
- new_entry(files, arg);
- continue;
- }
- sprintf(path, "%s%s", d, p);
- if (!strcmp(path, arg)) {
- argc = 0;
- if (f[1]) strcat(path, "\\.");
- } else {
- argc = 1;
- if (!f[0]) strcat(path, "\\");
- }
- while (!wild) {
- if (argc)
- sprintf(arg, "%s%s", path,
- ffblk.ff_name);
- else
- strcpy(arg, path);
- if (flags.f_directory) {
- new_entry(files, arg);
- } else if (ffblk.ff_attrib & FA_DIREC) {
- if (*ffblk.ff_name != '.')
- new_entry(dirs, arg);
- } else {
- new_entry(files, arg);
- }
- wild = findnext(&ffblk);
- }
- }
- last_entry(ndirs, dirs);
- last_entry(nfiles, files);
- }
-
- if (flags.f_all) FA_FILES |= FA_HIDDEN | FA_SYSTEM;
- wild = ls(nfiles, files);
- if (nfiles) free(files);
-
- for (i = 0; i < ndirs; ++i, ++dirs) {
- if (wild++) {
- if (!flags.f_zoo) printf("\n\n");
- onceover = 1;
- } else if (ndirs > 1) {
- onceover = 1;
- }
- ls(1, dirs);
- }
-
- break_func();
- exit(0);
- }
-
- static
- int
- break_func(void)
- {
- setdisk(main_dev);
- chdir(main_cwd);
- exit(0);
- }
-
- static
- int
- getarg(char c, char off)
- {
- switch (c) {
- case '1':
- flags.f_column = 0;
- if (off == '-') flags.f_column = 1;
- return(0);
- case 'C':
- if (!flags.f_long)
- flags.f_column = 1;
- if (off == '-')
- flags.f_column = 0;
- return(0);
- case 'F':
- flags.f_type = 1;
- if (off == '-') flags.f_type = 0;
- return(0);
- case 'P':
- flags.f_pwd = 1;
- if (off == '-') flags.f_pwd = 0;
- return(0);
- case 'R':
- flags.f_recursive = 1;
- if (off == '-') flags.f_recursive = 0;
- return(0);
- case 'S':
- flags.s_size = 1;
- if (off == '-') flags.s_size = 0;
- else flags.s_time = 0;
- return(0);
- case 'Z':
- flags.f_zoo = 1;
- if (off == '-') flags.f_zoo = 0;
- return(0);
- case 'a':
- flags.f_all = 1;
- if (off == '-') flags.f_all = 0;
- return(0);
- case 'd':
- flags.f_directory = 1;
- if (off == '-') flags.f_directory = 0;
- return(0);
- case 'f':
- flags.f_nosort = 1;
- if (off == '-') flags.f_nosort = 0;
- return(0);
- case 'l':
- flags.f_long = 1;
- if (off == '-') flags.f_long = 0;
- else flags.f_column = 0;
- return(0);
- case 'r':
- flags.s_reverse = 1;
- if (off == '-') flags.s_reverse = 0;
- return(0);
- case 's':
- flags.f_kilobyte = 1;
- if (off == '-') flags.f_kilobyte = 0;
- return(0);
- case 't':
- flags.s_time = 1;
- if (off == '-') flags.s_time = 0;
- else flags.s_size = 0;
- return(0);
- case 'H':
- case 'h':
- case '?':
- gethelp();
- return(1);
- default:
- return(0);
- }
- }
-
- static
- void
- gethelp()
- {
- printf("ls - list the contents of a directory");
- printf(" in alphabetical order\n");
- printf("\nusage:\tls [-1CFPRSZadflrst] name ...\n\n");
- printf("options:\n");
- printf("-1\tlist in one column format\n");
- printf("-C\tlist in multi-column format (default)\n");
- printf("-F\tdirectories are marked with a trailing '\\', ");
- printf("system files are marked\n");
- printf("\twith a trailing '@' and executable files are ");
- printf("marked with a trailing '*'\n");
- printf("-P\tprint the directory name before listing\n");
- printf("-R\trecursively list subdirectories\n");
- #ifdef SIZE_CL
- printf("-S\tsort by file size in bytes (cluster size if ");
- printf("option 's' is selected)\n");
- #else
- printf("-S\tsort by file size in bytes (size in kilobytes if ");
- printf("option 's' is selected)\n");
- #endif
- printf("-Z\tlist full pathnames in one column for input to ");
- printf("Zoo\n");
- printf("-a\tlist all entries including hidden and system ");
- printf("files\n");
- printf("-d\tlist directories as if they were a normal file\n");
- printf("-f\tdo not sort (list in the order files appear");
- printf(" in the directory)\n");
- #ifdef SIZE_CL
- printf("-l\tlist in long format ([size in clusters,] mode, ");
- #else
- printf("-l\tlist in long format ([size in kilobytes,] mode, ");
- #endif
- printf("size, date, name)\n");
- printf("-r\treverse the order of the selected sort\n");
- #ifdef SIZE_CL
- printf("-s\tlist the file size in clusters\n");
- #else
- printf("-s\tlist the file size in kilobytes\n");
- #endif
- printf("-t\tsort by time\n");
- printf("\nls parses the environment variable LS for options ");
- printf("before parsing the command\n");
- printf("line. options may be turned off with a trailing '-'");
- printf(" (i.e., ls -1F-s turns on\n");
- printf("the '1' and 's' options and turns off the 'F' ");
- printf("option).");
- }
-
- #ifdef SIZE_CL
- long cluster_size;
- #endif
-
- int sort_datum(void *a, void *b);
- void display_entries(int icd, int nitems, struct datum *items);
-
- int
- ls(int argc, char **argv)
- {
- int i;
- int nitems = 0;
- struct datum *items = (struct datum *) NULL;
- char **fargv = (char **) calloc(2, sizeof(char *));
-
- char *argv_dir, *cp;
- char ls_d[MAXDRIVE], ls_p[MAXDIR], ls_f[MAXFILE], ls_e[MAXEXT];
- char ls_pwd[MAXDRIVE+MAXDIR], ls_wd[MAXPATH];
- int argv_drive, icd, wild;
- struct fatinfo fi;
- struct ffblk ffblk;
- struct stat sbuf;
-
- if (!argc) return(0);
- if (!fargv) return(0);
-
- argv_drive = getdisk();
- parse_file(*argv, ls_d, ls_p, ls_f, ls_e);
- setdisk((int) (ls_d[0] - 'A'));
- sprintf(ls_pwd, "%s%s", ls_d, ls_p);
- argv_dir = getwd();
- icd = 0;
- if (!flags.f_directory)
- if (argc == 1 && !ls_f[0]) {
- icd = 1;
- chdir(ls_pwd);
- }
-
- /* run through the loop once for speed and (mostly) size savings
- */
- nitems = 0;
- for (i = 0; i < argc; ++i, ++argv)
- {
- if (icd)
- wild = findfirst("*.*", &ffblk, FA_FILES);
- else
- wild = findfirst(*argv, &ffblk, FA_FILES);
- while (!wild) {
- if (flags.f_directory) {
- if (ffblk.ff_attrib & ~FA_DIREC) {
- wild = findnext(&ffblk);
- continue;
- }
- } else {
- if (*ffblk.ff_name == '.')
- #ifdef DOT_AL
- if (onceover ||
- !(flags.f_all && flags.f_long))
- #else
- if (onceover || !flags.f_all)
- #endif
- {
- wild = findnext(&ffblk);
- continue;
- }
- }
- nitems++;
- wild = findnext(&ffblk);
- } /* while */
- } /* for */
- argv -= argc;
-
- if (!nitems) {
- if (!flags.f_zoo && onceover) printf("%s:", ls_pwd);
- return(0);
- }
-
- items = (struct datum *) calloc((nitems+1),
- sizeof(struct datum));
- if (!items) {
- if (onceover) fputc('\n', stderr);
- fprintf(stderr, "insufficient memory ");
- fprintf(stderr, "for %d entr%s", nitems,
- nitems > 1 ? "ies" : "y");
- return(1);
- }
-
- for (i = 0; i < argc; ++i, ++argv)
- {
- if (icd) {
- wild = findfirst("*.*", &ffblk, FA_FILES);
- getcwd(ls_wd, MAXPATH*sizeof(char));
- parse_file(ls_wd, ls_d, ls_p, ls_f, ls_e);
- if (ls_p[1])
- sprintf(ls_wd, "%s%s\\", ls_d, ls_p);
- else
- sprintf(ls_wd, "%s%s", ls_d, ls_p);
- } else
- {
- wild = findfirst(*argv, &ffblk, FA_FILES);
- ls_d[0] = **argv;
- ls_wd[0] = '\0';
- }
-
- #ifdef SIZE_CL
- getfat((int) (ls_d[0] - 'A' + 1), &fi);
- cluster_size = (long) (fi.fi_sclus * fi.fi_bysec);
- #endif
-
- while (!wild) {
- if (flags.f_directory) {
- if (ffblk.ff_attrib & ~FA_DIREC) {
- wild = findnext(&ffblk);
- continue;
- }
- } else {
- if (*ffblk.ff_name == '.')
- #ifdef DOT_AL
- if (onceover ||
- !(flags.f_all && flags.f_long))
- #else
- if (onceover || !flags.f_all)
- #endif
- {
- wild = findnext(&ffblk);
- continue;
- }
- }
-
- if (ls_wd[0])
- sprintf(items->pname, "%s%s", ls_wd,
- ffblk.ff_name);
- else
- sprintf(items->pname, "%s", *argv);
-
- stat(items->pname, &sbuf);
- items->date = (time_t) sbuf.st_atime;
-
- items->sizeb = ffblk.ff_fsize;
-
- items->attrib = (int) ffblk.ff_attrib;
- if (cp = strrchr(ffblk.ff_name, '.')) {
- if (!strcmp(++cp, "EXE"))
- items->attrib |= FA_EXEC;
- else if (!strcmp(cp, "COM"))
- items->attrib |= FA_EXEC;
- else if (!strcmp(cp, "BAT"))
- items->attrib |= FA_EXEC;
- if (ffblk.ff_attrib & FA_SYSTEM)
- items->attrib &= ~FA_EXEC;
- }
-
- items++;
- wild = findnext(&ffblk);
- } /* while */
- } /* for */
- argv -= argc;
- items -= nitems;
-
- chdir(argv_dir);
- free(argv_dir);
- setdisk(argv_drive);
-
- if (!flags.f_nosort)
- qsort(items, nitems, sizeof(struct datum), sort_datum);
-
- if (!flags.f_zoo) {
- if (onceover++) printf("%s:\n", ls_pwd);
- else if (flags.f_pwd) printf("%s\n", ls_pwd);
- display_entries(icd, nitems, items);
- } else {
- for (i = 0 ; i < nitems ; ++i, ++items)
- if (items->attrib & ~FA_DIREC)
- printf("%s\n", items->pname);
- items -= nitems;
- }
-
- if (!flags.f_directory)
- if (flags.f_recursive) {
- for (i = 0; i < nitems; ++i, ++items) {
- /*
- if (items->attrib & ~FA_DIREC) continue;
- */
- if (!(items->attrib & FA_DIREC)) continue;
- /* */
- if (*fname(items) == '.') continue;
- if (!flags.f_zoo) printf("\n\n");
- *fargv = items->pname;
- *(fargv+1) = (char *) NULL;
- ls(1, fargv);
- }
- items -= nitems;
- }
-
- free(fargv);
- free(items);
- return(1);
- }
-
- int
- sort_datum(void *ea, void *eb)
- {
- register struct datum *a = (struct datum *) ea;
- register struct datum *b = (struct datum *) eb;
- register int i;
- register long as, bs;
- register size_t al, bl;
- register char *ac = a->pname;
- register char *bc = b->pname;
-
- al = strlen(ac);
- bl = strlen(bc);
- if (flags.s_time) {
- as = (long) a->date;
- bs = (long) b->date;
- if (as - bs > 0L) i = -1;
- else if (as - bs < 0L) i = 1;
- else i = strncmp(ac, bc, al > bl ? bl : al);
- } else if (flags.s_size) {
- if (flags.f_kilobyte) {
- as = sizek(a);
- bs = sizek(b);
- } else {
- as = a->sizeb;
- bs = b->sizeb;
- }
- if (as - bs < 0L) i = -1;
- else if (as - bs > 0L) i = 1;
- else i = strncmp(ac, bc, al > bl ? bl : al);
- } else {
- i = strncmp(ac, bc, al > bl ? bl : al);
- }
- if (flags.s_reverse) i *= -1;
-
- if (i)
- return(i);
- else {
- if (flags.s_reverse && !flags.s_time && !flags.s_size)
- return( al < bl ? 1 : -1 );
- else
- return( al > bl ? 1 : -1 );
- }
- }
-
- static int display_largest;
- static int display_length;
- static short display_column;
- static short display_pname;
-
- static void display_entry(struct datum *sd);
-
- void
- display_entries(int icd, int nitems, struct datum *items)
- {
- long display_total;
-
- char *cp, pn1[MAXPATH], pn2[MAXPATH];
- int cnt, extra, i, j, loops, maybe, rows, total;
- int *pos;
- int lenmod, maxlen;
-
- if (!nitems) {
- if (flags.f_kilobyte || (icd && flags.f_long))
- printf("total 0\n");
- return;
- }
-
- display_pname = 0;
- strcpy(pn1, items->pname);
- cp = strrchr(pn1, '\\'), *cp = '\0';
- if (!pn1[2]) { pn1[2] = '\\'; pn1[3] = '\0'; }
- for (i = 0; i < nitems; ++i, ++items) {
- strcpy(pn2, items->pname);
- cp = strrchr(pn2, '\\'), *cp = '\0';
- if (!pn2[2]) { pn2[2] = '\\'; pn2[3] = '\0'; }
- if (strcmp(pn1, pn2)) {
- display_pname = 1;
- break;
- }
- else if (!icd && strcmp(main_cwd, pn2)) {
- display_pname = 1;
- break;
- }
- strcpy(pn1, pn2);
- }
- items -= i;
-
- display_total = maxlen = 0L;
- display_length = 0;
- for (i = 0; i < nitems; ++i, ++items) {
- display_total += sizek(items);
- maxlen = max(maxlen, sizek(items));
- if (display_pname)
- display_length = max(display_length,
- (int) strlen(items->pname));
- else
- display_length = max(display_length,
- (int) strlen(fname(items)));
- }
- items -= nitems;
- display_length += 3;
-
- if (flags.f_kilobyte) {
- display_largest = 2;
- while (maxlen /= 10L) display_largest++;
- } else
- display_largest = 0;
-
- if (flags.f_kilobyte || (icd && flags.f_long))
- printf("total %ld\n", display_total);
-
- pos = (int *) calloc((nitems+1), sizeof(int));
- if (!pos) return;
- for (i = 0; i < nitems; ++i, ++pos) *pos = 0;
- pos -= nitems;
-
- maxlen = display_largest + display_length;
- if (flags.f_kilobyte) maxlen++;
- if (flags.f_type) maxlen++;
- lenmod = 80 / maxlen;
-
- if (flags.f_column) {
- rows = nitems / lenmod;
- extra = nitems % lenmod;
- loops = rows + extra;
- total = 0;
- for (i = 0; i < loops; ++i) {
- cnt = i;
- if (cnt >= nitems) goto end;
- if (*(pos+cnt)) goto end;
- *(pos+cnt) = 1;
- total++;
- display_column = 0;
- display_entry(items+cnt);
-
- maybe = extra;
- for (j = 0; j < lenmod-1; ++j) {
- if (maybe-- > 0) cnt += rows + 1;
- else cnt += rows;
- if (cnt >= nitems) goto end;
- if (*(pos+cnt)) goto end;
- *(pos+cnt) = 1;
- total++;
- if (j < lenmod-2) {
- display_column = 0;
- display_entry(items+cnt);
- } else {
- display_column = 1;
- display_entry(items+cnt);
- if (total != nitems)
- putchar('\n');
- }
- }
-
- }
- } else { /* !flags.f_column */
- display_column = 1;
- for (i = 0; i < nitems-1; ++i, ++items) {
- display_entry(items);
- putchar('\n');
- }
- display_entry(items++);
- items -= nitems;
- }
-
- end:
- free(pos);
- return;
- }
-
- static
- void
- display_entry(struct datum *sd)
- {
- char fmt[6], ftime[13];
- char *cp, *filename;
- int i, itime, len;
-
- if (display_pname)
- filename = sd->pname;
- else
- filename = fname(sd);
- len = (int) strlen(filename);
-
- if (flags.f_long)
- {
- if (flags.f_kilobyte) {
- if (sd->attrib & FA_DIREC)
- printf(" ", sizek(sd));
- else
- printf("%7ld ", sizek(sd));
- }
-
- if (sd->attrib & FA_DIREC) putchar('d');
- else putchar('-');
- putchar('r');
- if (sd->attrib & FA_RDONLY) putchar('-');
- else putchar('w');
- if (sd->attrib & FA_EXEC) putchar('x');
- else putchar('-');
- if (sd->attrib & FA_HIDDEN) putchar('h');
- else putchar('-');
- if (sd->attrib & FA_SYSTEM) putchar('s');
- else putchar('-');
- if (sd->attrib & FA_ARCH) putchar('a');
- else putchar('-');
-
- if (sd->attrib & FA_DIREC)
- printf(" ", sd->sizeb);
- else
- printf("%10ld ", sd->sizeb);
-
- cp = asctime(localtime(&sd->date));
- itime = atoi(cp+20);
- if (itime != main_year)
- sprintf(ftime, "%6.6s%6d", cp+4, itime);
- else
- sprintf(ftime, "%12.12s", cp+4);
-
- printf("%s %s", ftime, filename);
- }
- else /* if (!flags.f_long) */
- {
- if (flags.f_kilobyte) {
- if (sd->attrib & FA_DIREC){
- for (i = 0; i <= display_largest; ++i)
- putchar(' ');
- } else {
- sprintf(fmt, "%%%dld ",
- display_largest);
- printf(fmt, sizek(sd));
- }
- }
-
- printf("%s", filename);
- }
-
- if (flags.f_type)
- {
- if (sd->attrib & FA_DIREC) putchar('\\'), len++;
- else if (sd->attrib & FA_EXEC) putchar('*'), len++;
- else if (sd->attrib & FA_SYSTEM) putchar('@'), len++;
- }
-
- if (!display_column)
- {
- for (i = len; i < display_length; ++i)
- putchar(' ');
- }
- }
-
- /*
- #include <dir.h>
- #include <dos.h>
- #include <string.h>
- */
-
- static int strpos(char *s, char c), strrpos(char *s, char c);
-
- int
- parse_file(char *pf_path,
- char *pf_d, char *pf_p, char *pf_f, char *pf_e)
- {
- char pf_cwd1[MAXPATH], pf_cwd2[MAXPATH];
- char pf_nwd[MAXPATH], *pf_twd;
- int pf_dev;
- int dp, pp, fp, ep;
- int pl;
- int pf_flag = 0x0;
- register int i, j;
-
- if (!pf_path) return(pf_flag);
-
- pf_dev = getdisk();
- getcwd(pf_cwd1, MAXPATH*sizeof(char));
-
- pl = (int) strlen(pf_path);
- for (i = 0; i < pl; ++i)
- if (*(pf_path+i) == '/') *(pf_path+i) = '\\';
- if (strchr(pf_path, '*'))
- pf_flag |= WILDCARDS;
- else if (strchr(pf_path, '?'))
- pf_flag |= WILDCARDS;
-
- dp = strpos(pf_path, ':');
- pp = dp + 1;
- fp = strrpos(pf_path, '\\')+1;
- if (!fp)
- fp = pp;
- ep = strrpos(pf_path, '.');
- if (ep < 0)
- ep = pl;
- else if (ep < fp)
- ep = pl;
- else if (ep > pl-2)
- ep = pl;
- else if (*(pf_path+(ep+1)) == '\\')
- ep = pl;
- if (*(pf_path+(ep-1)) == '.')
- fp = ep;
-
- *pf_d = *pf_p = *pf_f = *pf_e = '\0';
-
- /* find drive
- */
- if (dp > -1) {
- for (i = 0, j = 0; i < MAXDRIVE-1 && j < pp; ++i, ++j)
- {
- *(pf_d+i) = toupper(*(pf_path+j));
- *(pf_d+(i+1)) = '\0';
- if (!i) pf_flag |= DRIVE;
- }
- } else {
- sprintf(pf_d, "%c:", 'A' + getdisk());
- }
-
- /* find file name
- */
- if (fp > -1)
- for (i = 0, j = fp; i < MAXFILE-1 && j < ep; ++i, ++j)
- {
- *(pf_f+i) = toupper(*(pf_path+j));
- *(pf_f+(i+1)) = '\0';
- if (!i) pf_flag |= FILENAME;
- }
-
- /* find file extension
- */
- for (i = 0, j = ep; i < MAXEXT-1 && j < pl; ++i, ++j)
- {
- *(pf_e+i) = toupper(*(pf_path+j));
- *(pf_e+(i+1)) = '\0';
- if (!i) pf_flag |= EXTENSION;
- }
-
- /* find directory name
- */
- setdisk((int) (*pf_d - 'A'));
- getcwd(pf_cwd2, MAXPATH*sizeof(char));
-
- if (pp > -1)
- for (i = 0, j = pp; i < MAXDIR-1 && j < fp; ++i, ++j)
- {
- if (i &&
- *(pf_p+(i-1)) == '\\' &&
- *(pf_path+j) == '\\') {
- --i;
- } else {
- *(pf_p+i) = toupper(*(pf_path+j));
- *(pf_p+(i+1)) = '\0';
- if (!i) pf_flag |= DIRECTORY;
- }
- }
-
- /* if no directory found, use current directory
- */
- if (!*pf_p)
- sprintf(pf_p, ".");
-
- /* if there's a period in the directory, find the directory
- */
- if (strchr(pf_p, '.')) {
- if (*(pf_p+(fp-1)) == '\\')
- *(pf_p+(fp-1)) = '\0';
- strcpy(pf_nwd, pf_p);
- i = strpos((pf_p+1), '\\');
- if (i > -1) pf_nwd[i+1] = '\0';
- chdir(pf_nwd);
- pf_twd = pf_p;
- while ( (pf_twd = strchr(++pf_twd, '\\')) ) {
- strcpy(pf_nwd, pf_twd);
- i = strpos(&pf_nwd[1], '\\');
- if (i > -1) pf_nwd[i+1] = '\0';
- chdir(&pf_nwd[1]);
- }
- getcwd(pf_nwd, MAXPATH*sizeof(char));
- strcpy(pf_p, &pf_nwd[2]);
- }
-
- /* make sure that the directory name ends in a backslash
- */
- i = strlen(pf_p)-1;
- if (i < MAXDIR-2 && *(pf_p+i) != '\\') {
- *(pf_p+(i+1)) = '\\';
- *(pf_p+(i+2)) = '\0';
- }
-
- if (!*pf_f) {
- /* if there was no file name, strip the trailing
- * backslash from the directory name
- */
- i = strlen(pf_p)-1;
- if (i) *(pf_p+i) = '\0';
- } else {
- /* if the file name (including the file extension) is
- * a directory, reset the directory and clear the file
- * name and file extension
- */
- sprintf(pf_nwd, "%s%s%s", pf_p, pf_f, pf_e);
- if (!chdir(pf_nwd)) {
- strcpy(pf_p, pf_nwd);
- *pf_f = '\0';
- *pf_e = '\0';
- }
- }
-
- /* make sure the current directory for each disk is the same as
- * that when the subroutine was called
- */
- chdir(pf_cwd2);
- setdisk(pf_dev);
- chdir(pf_cwd1);
-
- return(pf_flag);
- }
-
- static
- int
- strpos(char *s, char c)
- {
- register int i = 0;
- register char *cp = s;
-
- for (; *cp; ++i) if (*cp++ == c) return(i);
- return(-1);
- }
-
- static
- int
- strrpos(char *s, char c)
- {
- register int i = (int) strlen(s) - 1;
- register char *cp = s+i;
-
- for (; i > -1; --i) if (*cp-- == c) return(i);
- return(-1);
- }
-
-