diff --git a/map.c b/map.c index 5726c58..5138082 100644 --- a/map.c +++ b/map.c @@ -28,9 +28,9 @@ static void show_map(uint8 *drvstr) if (flags & 0x80) { /* lokal DRIVE */ path[0]= '\\'; if (j < 2){ - strcpy(path, "DISK LW"); + strcpy(path, "maps to a local disk."); } else if (getcurdir(j+1, path+1)) { - strcpy(path, "LW !OK"); + strcpy(path, "maps to a local disk."); } } else { if (get_dir_path(dhandle, path)) { @@ -41,7 +41,7 @@ static void show_map(uint8 *drvstr) strcat(servern, "\\"); } else servern[0]='\0'; } - printf("MAP %c: = %s%s\n", (char)j+'A', servern, path); + if (flags & 0x80) printf("Drive %c: %s\n", (char)j+'A', path); else printf("Drive %c: = %s%s\n", (char)j+'A', servern, path); } } } @@ -58,9 +58,9 @@ static void do_map(int drive, NWPATH *nwp) if (flags & 0x80) { /* lokal DRIVE */ path[0]= '\\'; if (drive < 2){ - strcpy(path, "DISK LW"); + strcpy(path, "maps to a local disk."); } else if (getcurdir(drive+1, path+1)) { - strcpy(path, "LW !OK"); + strcpy(path, "maps to a local disk."); } } else { if (get_dir_path(dhandle, path)) { @@ -297,18 +297,192 @@ static int set_search(uint8 *drvstr, NWPATH *nwp, int pathmode) return(result); } + +static int path_is_drive_path(uint8 *path) +{ + if (!path || !path[0] || path[1] != ':') return(0); + if (path[0] >= 'A' && path[0] <= 'Z') return(1); + if (path[0] >= 'a' && path[0] <= 'z') return(1); + return(0); +} + +static void upstr_local(uint8 *s) +{ + while (*s) { + if (*s >= 'a' && *s <= 'z') *s -= 0x20; + s++; + } +} + +static int parse_pathins_arg(uint8 *drvstr, NWPATH *nwp, int argc, char *argv[], int mode) +{ + char joined[512]; + char *p; + char *q; + int slot = 0; + int k; + + *drvstr = '\0'; + memset(nwp, 0, sizeof(NWPATH)); + nwp->path = nwp->buff; + *(nwp->buff) = '\0'; + + if (argc < 2) return(1); + + joined[0] = '\0'; + for (k = 1; k < argc; k++) { + if (k > 1) strcat(joined, " "); + strncat(joined, argv[k], sizeof(joined) - strlen(joined) - 1); + } + + p = joined; + while (*p == ' ' || *p == '\t') p++; + + if (*p != 'S' && *p != 's') return(-1); + p++; + + while (*p >= '0' && *p <= '9') { + slot = slot * 10 + (*p - '0'); + p++; + } + + if (slot < 1 || slot > 16) return(-1); + if (*p != ':') return(-1); + p++; + + drvstr[0] = 's'; + drvstr[1] = (uint8)slot; + drvstr[2] = '\0'; + + while (*p == ' ' || *p == '\t') p++; + + if (mode == 1) { + /* PATHDEL S1: */ + return(0); + } + + if (*p == '=') p++; + while (*p == ' ' || *p == '\t') p++; + + if (!*p) return(-1); + + q = nwp->buff; + while (*p && (q - nwp->buff) < (int)sizeof(nwp->buff) - 1) { + *q++ = *p++; + } + *q = '\0'; + + upstr_local(nwp->buff); + nwp->path = nwp->buff; + + return(0); +} + +static int set_search_native(uint8 *drvstr, NWPATH *nwp, int pathmode) +{ + int result=-1; + SEARCH_VECTOR drives; + SEARCH_VECTOR_ENTRY *p=drives; + int j=0; + int entry = (*drvstr=='s') ? *(drvstr+1) : 0; + + get_search_drive_vektor(drives); + + while (p->drivenummer != 0xff && j++ < 16) { + if (!entry && path_is_drive_path(nwp->path) + && (p->drivenummer + 'A' == nwp->path[0])) entry=j; + + if (path_is_drive_path(nwp->path) + && p->drivenummer + 'A' == nwp->path[0] + && !strcmp(nwp->path+2, p->dospath)) { + p->drivenummer=0xfe; + *(p->dospath) = '\0'; + p->flags = 0; + } + p++; + } + + if (entry > 0) { + if (entry > 16) entry = 16; + + if (pathmode == 2 && entry <= j && entry < 16) { /* insert modus */ + int k=j+1-entry; + if (j < 16) { + p++; + k++; + j++; + } + while (k--) { + memcpy(p, p-1, sizeof(SEARCH_VECTOR_ENTRY)); + --p; + } + } + + if (--entry < j) + p = drives+entry; + else + (p+1)->drivenummer = 0xff; + + memset(p, 0, sizeof(SEARCH_VECTOR_ENTRY)); + + if (pathmode==1) { + p->drivenummer = 0xfe; + *(p->dospath) = '\0'; + result = set_search_drive_vektor(drives); + } else if (path_is_drive_path(nwp->path)) { + p->flags = 0; + p->drivenummer = (uint8)(nwp->path[0] - 'A'); + if (nwp->path[0] >= 'a' && nwp->path[0] <= 'z') + p->drivenummer = (uint8)(nwp->path[0] - 'a'); + strmaxcpy(p->dospath, nwp->path+2, sizeof(p->dospath)-1); + result = set_search_drive_vektor(drives); + } else { + /* + * Search path entries are not drive mappings. The original code stores + * the NetWare path text directly in dospath with drivenummer=0xfe. + * Client32 keeps/prints these entries correctly; allocating a permanent + * directory handle here made set_search_drive_vektor() return success, + * but the entry did not actually replace SEARCH1. + */ + p->flags = 0; + p->drivenummer = 0xfe; + strmaxcpy(p->dospath, nwp->path, sizeof(p->dospath)-1); + result = set_search_drive_vektor(drives); + } + } + + return(result); +} + + int func_path(int argc, char *argv[], int mode) { uint8 drvstr[22]; NWPATH nwpath; - if (!parse_argv(drvstr, &nwpath, argc, argv, 1, mode)) { + int rc; + + /* + * PATH/PATHINS/PATHDEL need their own parser. The old parse_argv() + * rejects common login-script syntax such as: + * PATHINS S1:=SYS:PUBLIC + * MAP INS S1:=SYS:PUBLIC + */ + if (argc < 2) { + show_search(""); + return(0); + } + + rc = parse_pathins_arg(drvstr, &nwpath, argc, argv, mode); + if (!rc) { int result=0; if (*(nwpath.path) || mode==1) - result=set_search(drvstr, &nwpath, mode); + result=set_search_native(drvstr, &nwpath, mode); if (mode != 1) show_search(drvstr); return(result); } + + fprintf(stderr, "Cannot interpret line. errcode=-1\n"); return(1); }