/* tools.c: 12-Jan-96 */ #include "net.h" /**************************************************************** * (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * ****************************************************************/ #ifdef __WATCOMC__ /* * Borland C compatibility wrappers used by the historical mars-nwe DOS tools. * Open Watcom does not provide getcurdir()/setdisk() under these Borland names. */ int getcurdir(int drive, char *directory) { REGS regs; SREGS sregs; regs.h.ah = 0x47; /* DOS: get current directory */ regs.h.dl = (unsigned char)drive; /* 0=current, 1=A:, 2=B:, ... */ sregs.ds = FP_SEG(directory); regs.x.si = FP_OFF(directory); intdosx(®s, ®s, &sregs); return(regs.x.cflag ? -1 : 0); } void setdisk(int drive) { REGS regs; regs.h.ah = 0x0e; /* DOS: select default drive */ regs.h.dl = (unsigned char)drive; /* 0=A:, 1=B:, ... */ intdos(®s, ®s); } #endif int key_pressed(void) { #ifdef __WATCOMC__ /* * Open Watcom's WORDREGS does not expose x.flags. The old Borland * code checked the BIOS INT 16h ZF bit after AH=01h. Open Watcom's * bios.h provides _bios_keybrd(), which wraps the same BIOS keyboard * service and returns 0 when no key is waiting. */ return(_bios_keybrd(_KEYBRD_READY) != 0); #else REGS regsin, regsout; regsin.h.ah = 0x01; /* read key-press */ int86(0x16, ®sin, ®sout); return((regsout.x.flags & 0x40) ? 0 : 1); /* zeroflag != 0 */ #endif } void clear_kb(void) { #ifdef __WATCOMC__ while (key_pressed()) { (void)_bios_keybrd(_KEYBRD_READ); } #else REGS regsin, regsout; while (key_pressed()) { /* zeroflag != 0 */ regsin.h.ah = 0x00; /* read key-press */ int86(0x16, ®sin, ®sout); } #endif } int ask_user(char *p, ...) { int key; int flag = 0; va_list argptr; va_start(argptr, p); vfprintf(stderr, p, argptr); va_end(argptr); fprintf(stderr, "\n Please answer: Y)es or N)o!"); while (1) { key = getch(); if (key == 'J' || key == 'j' || key== 'y' || key == 'Y') { fprintf(stderr, "Y\n\n"); flag = 1; break; } if (key == 'N' || key == 'n') { fprintf(stderr, "N\n\n"); flag = 0; break; } } clear_kb(); return(flag); } char *xmalloc(uint size) { char *p = (size) ? (char *)malloc(size) : (char*)NULL; if (p == (char *)NULL && size){ fprintf(stderr, "not enough core, need %d Bytes\n", size); exit(1); } return(p); } char *xcmalloc(uint size) { char *p = xmalloc(size); if (size) memset(p, 0, size); return(p); } void x_x_xfree(char **p) { if (*p != (char *)NULL){ free(*p); *p = (char*)NULL; } } int strmaxcpy(char *dest, char *source, int len) /* copied max. len chars + '\0' Byte */ { int slen = (source != (char *)NULL) ? min(len, strlen(source)) : 0; if (dest == (char *)NULL) return(0); if (slen) memcpy(dest, source, slen); dest[slen] = '\0'; return(slen); } char *xadd_char(char *s, int c, int maxlen) { if (s && maxlen) { int namlen = strlen(s); if (maxlen > -1 && namlen >= maxlen) namlen=maxlen-1; s[namlen++] = c; s[namlen] = '\0'; } return(s); } static uint8 down_char(uint8 ch) { if (ch > 64 && ch < 91) return(ch + 32); switch(ch){ case 142: ch = 132; break; case 153: ch = 148; break; case 154: ch = 129; break; default :break; } return(ch); } static uint8 up_char(uint8 ch) { if (ch > 96 && ch < 123) return(ch - 32); switch(ch) { case 132: ch = 142; break; case 148: ch = 153; break; case 129: ch = 154; break; default : break; } return(ch); } uint8 *upstr(uint8 *s) { if (!s) return((uint8*)NULL); for (;*s;s++) *s=up_char(*s); return(s); } void deb(uint8 *s) { if (!s || !*s) return; else { uint8 *p = s + strlen(s); while (p > s && (*--p==32 || *p==9));; if (*p==32 || *p==9) *p='\0'; else *(p+1) = '\0'; } } void leb(uint8 *s) { if (!s || !*s || (*s != 32 && *s != 9)) return; else { uint8 *p = s; for (;*p && *p!=32 && *p!=9;p++);; strcpy(s, p); } } void korrpath(char *s) { if (!s) return; for (;*s;s++) { if (*s=='\\') *s='/'; else *s=down_char(*s); } } void get_path_fn(char *s, char *p, char *fn) { int j= strlen(s); if (p != (char *)NULL) p[0] = 0; if (fn != (char*) NULL) fn[0] = 0; if (!j) return; if (s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0) ) ) { if (p != (char *)NULL) { strcpy(p, s); strcat(p, "/"); } if (fn != (char *)NULL) fn[0] = 0; return; } while (j--){ if ((s[j] == '/') || (s[j] == ':') ) { if (fn != (char *)NULL) strcpy(fn, s+j+1); if (p != (char *)NULL) { strncpy(p, s, j+1); p[j+1] = 0; } return; } } if (fn != (char *)NULL) strcpy(fn, s); /* no path */ } typedef struct { uint16 adr1; uint16 adr2; char reserve[6]; uint32 ladrs[3]; uint16 father_psp_seg; char handles[20]; uint16 environ_seg; } PROG_PSP; typedef struct { uint8 kennung; uint16 prozess_seg; uint16 blocks; } SPEICH_BLOCK; static char *getglobenvironment(uint16 *maxsize, uint16 *aktsize) { static uint16 globmaxenvsize=0; static char *globenviron=NULL; if (globenviron == (char *) NULL) { PROG_PSP *mypsp = MK_FP(_psp, 0); PROG_PSP *fatherpsp = MK_FP(mypsp->father_psp_seg, 0); SPEICH_BLOCK *spb = MK_FP(fatherpsp->environ_seg-1, 0); globenviron = (char *)MK_FP(fatherpsp->environ_seg, 0); globmaxenvsize = spb->blocks * 16; } if (globmaxenvsize){ char *search = globenviron; char *maxsearch = search+globmaxenvsize; while (*search && search < maxsearch) { int slen=strlen(search); search+=(slen+1); } *aktsize = max(2, (uint16)(search+1 - globenviron)); } else *aktsize=0; *maxsize = globmaxenvsize; /* printf("globenv=%p maxsize=%d, aktsize=%d\n", globenviron, globmaxenvsize, *aktsize); */ return(globenviron); } char *getglobenv(char *option) { uint16 maxenvsize; uint16 aktenvsize; char *search = getglobenvironment(&maxenvsize, &aktenvsize); int length = (option == NULL) ? 0 : strlen(option); if (aktenvsize && length){ char *maxsearch=search+aktenvsize; while (*search && search < maxsearch) { int slen=strlen(search); if (slen > length && (*(search + length) == '=') && (strncmp(search, option, length) == 0)) { /* printf("GET GLOB %s=%s\n", option, search+length+1); */ return(search + length + 1); } search+=(slen+1); } } return(NULL); } int putglobenv(char *option) { uint16 maxenvsize; uint16 aktenvsize; char *search = getglobenvironment(&maxenvsize, &aktenvsize); int optionlen = (option == NULL) ? 0 : strlen(option); /* printf("PUT GLOB option=%s\n", option); */ if (optionlen && maxenvsize){ int length; char *equal; for (equal = option; *equal && *equal != '='; equal++);; length = (int) (equal - option); if (length > 0 && *equal == '='){ char *maxsearch=search+aktenvsize; while (*search && search < maxsearch) { int slen = strlen(search); char *nextp = search+slen+1; if (slen > length && (*(search + length) == '=') && (strncmp(search, option, length) == 0)) { /* gefunden */ int diffsize = optionlen-slen; if (diffsize){ int movesize = (int)(maxsearch - nextp); if (diffsize > (int)(maxenvsize - aktenvsize)) return(-1); /* Kein Platz mehr */ if (!*(equal+1)) diffsize -= (length+2); xmemmove(nextp+diffsize, nextp, movesize); } if (*(equal+1)) strcpy(search, option); return(0); } search=nextp; } /* nicht gefunden , nun eintragen, falls m�glich */ if (*(equal+1) && optionlen < maxenvsize - aktenvsize) { strcpy(search, option); *(search+optionlen+1) = '\0'; /* letzter Eintrag '\0' nicht vergessen */ return(0); } else return(-1); } } return(-1); } int tool_page_line(int *line_count, int *continuous) { int ch; if (!line_count || !continuous) return(0); if (*continuous) return(0); (*line_count)++; if (*line_count < 24) return(0); fprintf(stdout, "Press any key to continue ('C' for continue)"); fflush(stdout); ch = getch(); fprintf(stdout, "\n"); if (ch == 'c' || ch == 'C') *continuous = 1; *line_count = 0; return(0); } /**************************************************************** * Shared helpers for the newer DOS utility frontends. * * These deliberately stay in tools.c instead of in grant/revoke/remove/ * rights/flagdir so the current multicall binary and possible future * grouped multicall binaries can reuse the same code without dragging in * command-specific modules. ****************************************************************/ int tool_strsame(char *a, char *b) { if (!a) a = ""; if (!b) b = ""; while (*a || *b) { int ca = *a++; int cb = *b++; if (ca >= 'a' && ca <= 'z') ca -= 32; if (cb >= 'a' && cb <= 'z') cb -= 32; if (ca != cb) return(0); } return(1); } int tool_is_help_arg(char *s) { if (!s) return(0); return(tool_strsame(s, "/?") || tool_strsame(s, "-?") || tool_strsame(s, "?")); } int tool_is_option(char *s) { if (!s) return(0); return(s[0] == '/' || s[0] == '-'); } int tool_is_files_option(char *s) { if (!s) return(0); return(tool_strsame(s, "/FILES") || tool_strsame(s, "-FILES") || tool_strsame(s, "/F") || tool_strsame(s, "-F")); } int tool_is_subdirs_option(char *s) { if (!s) return(0); return(tool_strsame(s, "/SUBDIRS") || tool_strsame(s, "-SUBDIRS") || tool_strsame(s, "/SUBDIRECTORIES") || tool_strsame(s, "-SUBDIRECTORIES") || tool_strsame(s, "/S") || tool_strsame(s, "-S")); } int tool_get_current_drive(void) { REGS regs; regs.h.ah = 0x19; int86(0x21, ®s, ®s); return((int)regs.h.al); } int tool_current_dhandle(uint8 *connid, uint8 *dhandle) { uint8 flags = 0; int drive = tool_get_current_drive(); if (get_drive_info((uint8)drive, connid, dhandle, &flags)) return(-1); if (!*connid || (flags & 0x80)) return(-1); return(0); } int tool_current_prefix(char *out, int max) { uint8 connid = 0; uint8 dhandle = 0; uint8 flags = 0; int drive; char server[52]; char dpath[260]; char volume[32]; char *p; int i = 0; if (!out || max < 8) return(-1); out[0] = '\0'; drive = tool_get_current_drive(); if (get_drive_info((uint8)drive, &connid, &dhandle, &flags)) return(-1); if (!connid || (flags & 0x80)) return(-1); server[0] = '\0'; if (get_fs_name(connid, server)) server[0] = '\0'; dpath[0] = '\0'; if (get_dir_path(dhandle, dpath) || !dpath[0]) return(-1); p = strchr(dpath, ':'); if (!p) return(-1); while (dpath + i < p && i < (int)sizeof(volume) - 1) { volume[i] = dpath[i]; i++; } volume[i] = '\0'; if (!volume[0]) return(-1); if (server[0]) sprintf(out, "%s/%s:", server, volume); else sprintf(out, "%s:", volume); return(0); } int tool_is_current_path(char *path) { if (!path || !*path) return(1); if (tool_strsame(path, ".")) return(1); if (tool_strsame(path, ".\\")) return(1); if (tool_strsame(path, "./")) return(1); return(0); } void tool_upcopy(char *dst, char *src, int max) { int i = 0; if (!src) src = ""; while (*src && i < max - 1) { char c = *src++; if (c == '/') c = '\\'; if (c >= 'a' && c <= 'z') c -= 32; dst[i++] = c; } dst[i] = 0; } void tool_basename(char *dst, char *src, int max) { char up[260]; char *p; tool_upcopy(up, src, sizeof(up)); p = strrchr(up, '\\'); if (!p) p = strrchr(up, ':'); if (p) strmaxcpy(dst, p + 1, max - 1); else strmaxcpy(dst, up, max - 1); } void tool_header_path(char *out, char *path, int max) { char prefix[90]; char up[260]; if (tool_current_prefix(prefix, sizeof(prefix))) prefix[0] = '\0'; if (tool_is_current_path(path)) { strmaxcpy(out, prefix, max - 1); return; } tool_upcopy(up, path, sizeof(up)); strmaxcpy(out, prefix, max - 1); if ((int)(strlen(out) + strlen(up)) < max - 1) strcat(out, up); } int tool_is_dot_dir(char *name) { if (!name) return(0); if (name[0] == '.' && name[1] == '\0') return(1); if (name[0] == '.' && name[1] == '.' && name[2] == '\0') return(1); return(0); } void tool_join_path(char *out, char *base, char *name, int max) { int len; out[0] = '\0'; strmaxcpy(out, base, max - 1); len = strlen(out); if (len > 0 && out[len - 1] != '\\' && out[len - 1] != '/' && out[len - 1] != ':') { if (len < max - 1) { out[len++] = '\\'; out[len] = '\0'; } } if ((int)(strlen(out) + strlen(name)) < max - 1) strcat(out, name); } int tool_has_wildcards(char *path) { if (!path) return(0); while (*path) { if (*path == '*' || *path == '?') return(1); path++; } return(0); } void tool_parent_pattern(char *dir, char *pattern, char *path, int maxdir, int maxpat) { char tmp[260]; char *p; tool_upcopy(tmp, path, sizeof(tmp)); p = strrchr(tmp, '\\'); if (!p) p = strrchr(tmp, ':'); if (p) { if (*p == ':') { p++; strmaxcpy(pattern, p, maxpat - 1); *p = '\0'; strmaxcpy(dir, tmp, maxdir - 1); } else { strmaxcpy(pattern, p + 1, maxpat - 1); *p = '\0'; strmaxcpy(dir, tmp, maxdir - 1); } } else { strmaxcpy(dir, ".", maxdir - 1); strmaxcpy(pattern, tmp, maxpat - 1); } if (!pattern[0]) strmaxcpy(pattern, "*.*", maxpat - 1); }