/* Program kcd.c ** ** Change Directory for 4DOS ** ** Original code by: ? ** ** Modified and corrected by S. E. Kohn ** ** Requires 4DOS environmental variable CDPATH be set to list of ** primary directories to search. ** Program will work for partial directory names ** ** Use 4DOS alias cd=`:\\kcd.com` ** */ #include #include #include #include #include #include #define CDPATH "CDPATH" #define MAX_DIR 66 #define PROG "cd" /* ##################### IS_ROOT_DIR ######################## */ int is_root_dir (char try[]) { char *ptr; if ((ptr = strchr(try, ':')) != NULL) ptr++; else ptr = try; if (strchr("\\/", *ptr) != NULL && *(ptr+1) == '\0') return 1; if (strchr("\\/", *ptr) != NULL && *(ptr+1) == '.' && *(ptr+2) == '\0') return 1; return 0; } /* ####################### ISDIR ##################### */ int isdir (char try[]) { struct find_t find; char *ptr, test[MAX_DIR]; if (is_root_dir(try)) return 1; if ((_dos_findfirst(try, 0xffff, &find) == 0) && (find.attrib & _A_SUBDIR)) return 1; strcpy(test, try); strcat(test, "*"); if (_dos_findfirst(test, 0xffff, &find) == 0) { if (find.attrib & _A_SUBDIR) { ptr = strrchr(try, '\\'); if (ptr != (char *)NULL) strcpy(++ptr, find.name); else strcpy(try, find.name); return 1; } while (_dos_findnext(&find) == 0) { if (find.attrib & _A_SUBDIR) { ptr = strrchr(try, '\\'); if (ptr != (char *)NULL) strcpy(++ptr, find.name); else strcpy(try, find.name); return 1; } } } if (try[strlen(try)-2] == ':' && try[strlen(try)-1] == '.') { try[strlen(try)-1] = '\\'; return 1; } return 0; } /* ######################## ISABSOLUTEPATH ################### */ int isabsolutepath(char try[]) { return strchr("\\/", try[0]) != NULL || (try[1] == ':' && strchr("\\/", try[2]) != NULL); } /* ###################### KCD ##################### */ int main (int argc, char *argv[]) { char *cdpath, dir[MAX_DIR], *nxt, drv='\0', *check, try[MAX_DIR], *ptr, root[MAX_DIR]; unsigned orig_drive, trg_drive, tmp; int fnd, cdpathno = 0; /* get current default drive */ _dos_getdrive (&orig_drive); strcpy(root, "c:\\"); root[0] = 'a' + orig_drive - 1; if (argc == 1) { /* if no arguments, print current directory */ getcwd(dir, MAX_DIR); strlwr(dir); printf("%s\n", dir); return 0; } strcpy (try, argv[1]); if (try[0] == '-') strcpy(dir, getenv("LASTDIR")); else { while ((ptr = strchr(try, '/')) != (char *)NULL) *ptr = '\\'; if (try[strlen(try)-1] == ':') strcat (try, "."); if ((cdpath = getenv(CDPATH)) == NULL || isdir(try) || isabsolutepath(try) || try[0] == '.') /* * if either cdpath not defined, valid subdir given, or ".." used in * relative path, don't bother searching cdpath */ strcpy (dir, try); else { strcpy (dir, ".\\"); strcat (dir, try); do { root[3] = '\0'; /* * if dir given on command line is subdirectory of current directory, * no need to search cdpath */ if (!isdir(dir) && ((nxt = strtok(cdpath, ";")) != NULL)) { /* if drive is part of dir, save */ if ((check = strchr(try, ':')) != NULL) { drv = *(check-1); check++; } else check = try; strcat(root, try); fnd = isdir(root); /* * search each entry in cdpath (left to right) to find first for * which argv[1] is a subdirectory or until cdpath exhausted */ do { if (fnd) { strcpy(dir, root); break; } strcpy(dir, nxt); if (dir[strlen(dir)-1] != '\\') strcat(dir, "\\"); strcat(dir, check); if(isdir(dir) && (drv == '\0' || strchr(dir, ':') == NULL || drv == dir[0])) fnd = 1; } while(!fnd && ((nxt = strtok(NULL, ";")) != NULL)); } cdpathno++; if (!fnd) sprintf(cdpath, "CDPATH%d", cdpathno); } while(!fnd && ((cdpath = getenv(cdpath)) != (char *)NULL)); /* print error if directory not found in cdpath */ if (!fnd) { fprintf (stderr, "%s: Directory %s not found.\n", PROG, argv[1]); return -1; } } } /* * if directory ends in '\' and is NOT the root directory of a drive, strip * off the '\' */ if((dir[strlen(dir)-1] == '\\' || dir[strlen(dir)-1] == '/') && !is_root_dir(dir)) dir[strlen(dir)-1] = '\0'; /* * if drive is part of target directory and it differs from the current * default, set drive before performing chdir */ if (strchr(dir, ':') != NULL && (trg_drive = dir[0] + 1 - (isupper(dir[0]) ? 'A' : 'a')) != orig_drive) _dos_setdrive(trg_drive, &tmp); while (strncmp(dir, "...", 3) == 0) { getcwd(try, MAX_DIR); if (is_root_dir(try) == 0) chdir(".."); strcpy(dir, dir + 1); } getcwd(try, MAX_DIR); if (is_root_dir(try) && (strcmp(dir, "..") == 0)) return 0; if (chdir(dir) != 0) { fprintf (stderr, "%s: Invalid directory %s.\n", PROG, argv[1]); exit (1); } return 0; }