commit 5e6805dd31bb9cb04168fce10368e6e1397f2858 Author: Mario Fetka Date: Sun Nov 13 00:40:40 2011 +0100 mars_dosutils-0.01 diff --git a/doc b/doc new file mode 100755 index 0000000..9b7bb04 --- /dev/null +++ b/doc @@ -0,0 +1,46 @@ +/* DOC for NET.EXE */ +This is a short description of net.exe which is a simple DOS-client +programm to allow standard NCP network actions, mainly for mars_nwe. +All functions are called as a second parameter. +This programm is very incomplete till now, but some functions +works well with mars_nwe. + +LOGOUT: +Logout from a NCP Server. + +LOGIN: +usage: LOGIN [-u] [user | user password] +-u = use unencrypted password. +With this function you can log into a NCP Server. +Its only make a login, no mappings or something else. + +If you want a login similar to NOVELL's login.exe you should +do it with a batch job. + +example: +[\LOGIN\LOGIN.BAT] +@echo OFF +net logout +net login %1 %2 %3 +if errorlevel 1 goto :end +map h:=HOME: +if not exist h:\profile.bat goto :end +h: +profile.bat +:end + +PASSWD: +usage: PASSWD [user] +With this function you are able to change a users password. +This call uses the old unencryted change password call !! + + +PATH: +usage: PATH sn:[=[path]] + sn = 's1' .. 's16' + +With this function a new path element can be created. +Its only sets the path environment. + + + diff --git a/e.pck b/e.pck new file mode 100755 index 0000000..da7271c Binary files /dev/null and b/e.pck differ diff --git a/kern.asm b/kern.asm new file mode 100755 index 0000000..76dd433 --- /dev/null +++ b/kern.asm @@ -0,0 +1,201 @@ +; kern.asm: 20-Nov-93, 21:52 +IDEAL +P286 +MODEL LARGE +; Fuer Turboc gerettet werden muessen folgende Register: +; BP, SS, SP, DS, CS u. SI, DI + +MACRO P_START + push bp + mov bp, sp +ENDM + +MACRO P_END + pop bp +ENDM + +MACRO PUSH_REGS + push ds + push si + push di +ENDM + +MACRO POP_REGS + pop di + pop si + pop ds +ENDM + +;; EXTRN _esr_routine:FAR + +PUBLIC _IPXinit; +PUBLIC _IPXopen_socket; +PUBLIC _IPXclose_socket; +PUBLIC _IPXlisten; +;; PUBLIC _asm_esr_routine; +PUBLIC _xmemmove; +PUBLIC _Net_Call; + +DATASEG +enterIPX DD FAR + +CODESEG +PROC _IPXinit; + P_START + PUSH_REGS + mov ax, 7A00h + int 2Fh + cmp al, 0FFh + jne @@fertig + mov cx, @data + mov ds, cx + mov [WORD PTR enterIPX], di + mov ax, es + mov [WORD PTR enterIPX+2], ax + mov al, 1 ; OK +@@fertig: + mov ah, 0 + POP_REGS + P_END + ret ; OK = 1 ; nicht ok = 0 +ENDP + +PROC _xmemmove; + ARG z:DATAPTR, q:DATAPTR, nmbr:WORD; Argumente + cli ; Disable Interrupts + push bp + mov bp,sp + mov cx, [nmbr]; + or cx, cx; + jz @@fertig; Anzahl ist 0; + push ds; + push si; + push di; + pushf + lds si, [q] ; Quelle + les di, [z] ; Ziel + cmp di, si ; + jl @@L1 ; Ziel ist kleiner + std ; Richtungsflag setzen + dec cx + add di, cx ; Von oben nach unten kopieren + add si, cx ; + inc cx ; alten Wert wiederherstellen + jmp @@L2; + @@L1: + cld ; Richtungsflag loeschen + @@L2: ; und nun das eigentliche kopieren + REP movsb ; + popf + pop di; + pop si; + pop ds; + @@fertig: + pop bp; + sti ; enable Interrupts + ret +ENDP + +PROC _IPXopen_socket; + ARG sock:WORD, live:WORD + P_START + PUSH_REGS + mov ax, [live] + mov dx, [sock] + mov bx, @data + mov ds, bx + mov bx, 0 + call [enterIPX] + cmp al, 0FFh + jne @@L1 + mov ax, -1 ; Socket already open + jmp @@L3 +@@L1: + cmp al, 0FEh + jne @@L2 + mov ax, -2 ; Socket Table full + jmp @@L3 +@@L2: + mov ax, dx +@@L3: + POP_REGS + P_END + ret +ENDP + +PROC _IPXclose_socket; + ARG sock:WORD + P_START + PUSH_REGS + mov dx, [sock] + mov bx, @data + mov ds, bx + mov bx, 1 + call [enterIPX] + POP_REGS + P_END + ret +ENDP + +PROC _IPXlisten; + ARG ecb:DATAPTR + P_START + PUSH_REGS + les si, [ecb] ; Adresse ecb + mov bx, @data + mov ds, bx + mov bx, 4 + call [enterIPX] + POP_REGS + P_END + mov ah, 0 + ret +ENDP + +;; PROC _asm_esr_routine; +;; push bp; +;; PUSH_REGS; +;; mov ax, @data +;; mov ds, ax ; Fr C PROGRAMM +;; push es; Adressegment vom EBC +;; push si; Adressoffset vom ECB +;; call _esr_routine; C ROUTINE +;; pop si; +;; pop es; +;; POP_REGS; +;; pop bp; +;; cli ; no Interrupt says NOVELL +;; ret +;; ENDP + + +PROC _Net_Call; + ARG func:WORD, req:DATAPTR, repl:DATAPTR; Argumente + push bp + mov bp, sp + mov ax, [func]; + push ds; + push si; + push di; + pushf + lds si, [req] ; Request + les di, [repl] ; Reply + int 21h + popf + pop di; + pop si; + pop ds; + pop bp; + mov ah, 0 + ret +ENDP + +END + + + + + + + + diff --git a/kern.h b/kern.h new file mode 100755 index 0000000..6344225 --- /dev/null +++ b/kern.h @@ -0,0 +1,12 @@ +/* kern.h Assembler Routinen 20-Nov-93 */ +extern int IPXinit(void); +extern int IPXopen_socket(UI sock, int live); +extern void IPXclose_socket(UI sock); +extern int IPXlisten(ECB *ecb); +extern void asm_esr_routine(void); +extern void esr_routine(ECB *ecb); +extern void xmemmove(void *ziel, void *quelle, UI anz); +extern int Net_Call(UI func, void *req, void *repl); + + + diff --git a/kern.lst b/kern.lst new file mode 100755 index 0000000..96fd9cc --- /dev/null +++ b/kern.lst @@ -0,0 +1,317 @@ +Turbo Assembler Version 3.1 28/04/96 13:28:50 Page 1 +kern.asm + + + + 1 ; kern.asm: 20-Nov-93, 21:52 + 2 IDEAL + 3 P286 + 4 0000 MODEL LARGE + 5 ; Fuer Turboc gerettet werden muessen folgende Register: + 6 ; BP, SS, SP, DS, CS u. SI, DI + 7 + 8 MACRO P_START + 9 push bp + 10 mov bp, sp + 11 ENDM + 12 + 13 MACRO P_END + 14 pop bp + 15 ENDM + 16 + 17 MACRO PUSH_REGS + 18 push ds + 19 push si + 20 push di + 21 ENDM + 22 + 23 MACRO POP_REGS + 24 pop di + 25 pop si + 26 pop ds + 27 ENDM + 28 + 29 ;; EXTRN _esr_routine:FAR + 30 + 31 PUBLIC _IPXinit; + 32 PUBLIC _IPXopen_socket; + 33 PUBLIC _IPXclose_socket; + 34 PUBLIC _IPXlisten; + 35 ;; PUBLIC _asm_esr_routine; + 36 PUBLIC _xmemmove; + 37 PUBLIC _Net_Call; + 38 + 39 0000 DATASEG + 40 0000 0000FFFE enterIPX DD FAR + 41 + 42 0004 CODESEG + 43 0000 PROC _IPXinit; + 44 P_START +1 45 0000 55 push bp +1 46 0001 8B EC mov bp, sp + 47 PUSH_REGS +1 48 0003 1E push ds +1 49 0004 56 push si +1 50 0005 57 push di + 51 0006 B8 7A00 mov ax, 7A00h + 52 0009 CD 2F int 2Fh + 53 000B 3C FF cmp al, 0FFh + 54 000D 75 10 jne @@fertig + 55 000F B9 0000s mov cx, @data + 56 0012 8E D9 mov ds, cx + 57 0014 89 3E 0000r mov [WORD PTR enterIPX], di + Turbo Assembler Version 3.1 28/04/96 13:28:50 Page 2 +kern.asm + + + + 58 0018 8C C0 mov ax, es + 59 001A A3 0002r mov [WORD PTR enterIPX+2], ax + 60 001D B0 01 mov al, 1 ; OK + 61 001F @@fertig: + 62 001F B4 00 mov ah, 0 + 63 POP_REGS +1 64 0021 5F pop di +1 65 0022 5E pop si +1 66 0023 1F pop ds + 67 P_END +1 68 0024 5D pop bp + 69 0025 CB ret ; OK = 1 ; nicht ok = 0 + 70 0026 ENDP + 71 + 72 0026 PROC _xmemmove; + 73 ARG z:DATAPTR, q:DATAPTR, nmbr:WORD; Argumente + 74 0026 FA cli ; Disable Interrupts + 75 0027 55 push bp + 76 0028 8B EC mov bp,sp + 77 002A 8B 4E 0E mov cx, [nmbr]; + 78 002D 0B C9 or cx, cx; + 79 002F 74 1F jz @@fertig; Anzahl ist 0; + 80 0031 1E push ds; + 81 0032 56 push si; + 82 0033 57 push di; + 83 0034 9C pushf + 84 0035 C5 76 0A lds si, [q] ; Quelle + 85 0038 C4 7E 06 les di, [z] ; Ziel + 86 003B 3B FE cmp di, si ; + 87 003D 7C 0A jl @@L1 ; Ziel ist kleiner + 88 003F FD std ; Richtungsflag setzen + 89 0040 49 dec cx + 90 0041 03 F9 add di, cx ; Von oben nach unten kopieren + 91 0043 03 F1 add si, cx ; + 92 0045 41 inc cx ; alten Wert wiederherstellen + 93 0046 EB 02 90 jmp @@L2; + 94 0049 @@L1: + 95 0049 FC cld ; Richtungsflag loeschen + 96 004A @@L2: ; und nun das eigentliche kopieren + 97 004A F3> A4 REP movsb ; + 98 004C 9D popf + 99 004D 5F pop di; + 100 004E 5E pop si; + 101 004F 1F pop ds; + 102 0050 @@fertig: + 103 0050 5D pop bp; + 104 0051 FB sti ; enable Interrupts + 105 0052 CB ret + 106 0053 ENDP + 107 + 108 0053 PROC _IPXopen_socket; + 109 ARG sock:WORD, live:WORD + 110 P_START +1 111 0053 55 push bp +1 112 0054 8B EC mov bp, sp + 113 PUSH_REGS +1 114 0056 1E push ds + Turbo Assembler Version 3.1 28/04/96 13:28:50 Page 3 +kern.asm + + + +1 115 0057 56 push si +1 116 0058 57 push di + 117 0059 8B 46 08 mov ax, [live] + 118 005C 8B 56 06 mov dx, [sock] + 119 005F BB 0000s mov bx, @data + 120 0062 8E DB mov ds, bx + 121 0064 BB 0000 mov bx, 0 + 122 0067 FF 1E 0000r call [enterIPX] + 123 006B 3C FF cmp al, 0FFh + 124 006D 75 06 jne @@L1 + 125 006F B8 FFFF mov ax, -1 ; Socket already open + 126 0072 EB 0D 90 jmp @@L3 + 127 0075 @@L1: + 128 0075 3C FE cmp al, 0FEh + 129 0077 75 06 jne @@L2 + 130 0079 B8 FFFE mov ax, -2 ; Socket Table full + 131 007C EB 03 90 jmp @@L3 + 132 007F @@L2: + 133 007F 8B C2 mov ax, dx + 134 0081 @@L3: + 135 POP_REGS +1 136 0081 5F pop di +1 137 0082 5E pop si +1 138 0083 1F pop ds + 139 P_END +1 140 0084 5D pop bp + 141 0085 CB ret + 142 0086 ENDP + 143 + 144 0086 PROC _IPXclose_socket; + 145 ARG sock:WORD + 146 P_START +1 147 0086 55 push bp +1 148 0087 8B EC mov bp, sp + 149 PUSH_REGS +1 150 0089 1E push ds +1 151 008A 56 push si +1 152 008B 57 push di + 153 008C 8B 56 06 mov dx, [sock] + 154 008F BB 0000s mov bx, @data + 155 0092 8E DB mov ds, bx + 156 0094 BB 0001 mov bx, 1 + 157 0097 FF 1E 0000r call [enterIPX] + 158 POP_REGS +1 159 009B 5F pop di +1 160 009C 5E pop si +1 161 009D 1F pop ds + 162 P_END +1 163 009E 5D pop bp + 164 009F CB ret + 165 00A0 ENDP + 166 + 167 00A0 PROC _IPXlisten; + 168 ARG ecb:DATAPTR + 169 P_START +1 170 00A0 55 push bp +1 171 00A1 8B EC mov bp, sp + Turbo Assembler Version 3.1 28/04/96 13:28:50 Page 4 +kern.asm + + + + 172 PUSH_REGS +1 173 00A3 1E push ds +1 174 00A4 56 push si +1 175 00A5 57 push di + 176 00A6 C4 76 06 les si, [ecb] ; Adresse ecb + 177 00A9 BB 0000s mov bx, @data + 178 00AC 8E DB mov ds, bx + 179 00AE BB 0004 mov bx, 4 + 180 00B1 FF 1E 0000r call [enterIPX] + 181 POP_REGS +1 182 00B5 5F pop di +1 183 00B6 5E pop si +1 184 00B7 1F pop ds + 185 P_END +1 186 00B8 5D pop bp + 187 00B9 B4 00 mov ah, 0 + 188 00BB CB ret + 189 00BC ENDP + 190 + 191 ;; PROC _asm_esr_routine; + 192 ;; push bp; + 193 ;; PUSH_REGS; + 194 ;; mov ax, @data + 195 ;; mov ds, ax ; Fr C PROGRAMM + 196 ;; push es; Adressegment vom EBC + 197 ;; push si; Adressoffset vom ECB + 198 ;; call _esr_routine; C ROUTINE + 199 ;; pop si; + 200 ;; pop es; + 201 ;; POP_REGS; + 202 ;; pop bp; + 203 ;; cli ; no Interrupt says NOVELL + 204 ;; ret + 205 ;; ENDP + 206 + 207 + 208 00BC PROC _Net_Call; + 209 ARG func:WORD, req:DATAPTR, repl:DATAPTR; Argumente + 210 00BC 55 push bp + 211 00BD 8B EC mov bp, sp + 212 00BF 8B 46 06 mov ax, [func]; + 213 00C2 1E push ds; + 214 00C3 56 push si; + 215 00C4 57 push di; + 216 00C5 9C pushf + 217 00C6 C5 76 08 lds si, [req] ; Request + 218 00C9 C4 7E 0C les di, [repl] ; Reply + 219 00CC CD 21 int 21h + 220 00CE 9D popf + 221 00CF 5F pop di; + 222 00D0 5E pop si; + 223 00D1 1F pop ds; + 224 00D2 5D pop bp; + 225 00D3 B4 00 mov ah, 0 + 226 00D5 CB ret + 227 00D6 ENDP + 228 + Turbo Assembler Version 3.1 28/04/96 13:28:50 Page 5 +kern.asm + + + + 229 END + Turbo Assembler Version 3.1 28/04/96 13:28:50 Page 6 +Symbol Table + + + + +Symbol Name Type Value + +??DATE Text "28/04/96" +??FILENAME Text "kern " +??TIME Text "13:28:50" +??VERSION Number 030A +@32BIT Text 0 +@@FERTIG Near KERN_TEXT:001F +@@FERTIG Near KERN_TEXT:0050 +@@L1 Near KERN_TEXT:0049 +@@L1 Near KERN_TEXT:0075 +@@L2 Near KERN_TEXT:004A +@@L2 Near KERN_TEXT:007F +@@L3 Near KERN_TEXT:0081 +@CODE Text KERN_TEXT +@CODESIZE Text 1 +@CPU Text 0787H +@CURSEG Text KERN_TEXT +@DATA Text DGROUP +@DATASIZE Text 1 +@FILENAME Text KERN +@INTERFACE Text 00H +@MODEL Text 5 +@STACK Text DGROUP +@WORDSIZE Text 2 +ECB Number [DGROUP:BP+0006] +ENTERIPX Dword DGROUP:0000 +FUNC Number [DGROUP:BP+0006] +LIVE Number [DGROUP:BP+0008] +NMBR Number [DGROUP:BP+000E] +Q Number [DGROUP:BP+000A] +REPL Number [DGROUP:BP+000C] +REQ Number [DGROUP:BP+0008] +SOCK Number [DGROUP:BP+0006] +Z Number [DGROUP:BP+0006] +_IPXCLOSE_SOCKET + Far KERN_TEXT:0086 +(_IPXclose_socket) +_IPXINIT (_IPXinit) Far KERN_TEXT:0000 +_IPXLISTEN (_IPXlisten) Far KERN_TEXT:00A0 +_IPXOPEN_SOCKET + Far KERN_TEXT:0053 +(_IPXopen_socket) +_NET_CALL (_Net_Call) Far KERN_TEXT:00BC +_XMEMMOVE (_xmemmove) Far KERN_TEXT:0026 + +Macro Name + +POP_REGS +PUSH_REGS +P_END +P_START + +Groups & Segments Bit Size Align Combine Class + +DGROUP Group + _DATA 16 0004 Word Public DATA +KERN_TEXT 16 00D6 Word Public CODE + \ No newline at end of file diff --git a/login.bat b/login.bat new file mode 100755 index 0000000..74ee3df --- /dev/null +++ b/login.bat @@ -0,0 +1,4 @@ +c:\net logout +c:\net login %1 %2 %3 +map h:=HOME: + diff --git a/login.c b/login.c new file mode 100755 index 0000000..2ceca64 --- /dev/null +++ b/login.c @@ -0,0 +1,215 @@ +/* login.c 05-Apr-96 */ + +/**************************************************************** + * (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * + ****************************************************************/ + +#include "net.h" +#include "nwcrypt.h" + + +static int do_change_object_passwd(char *name, + uint16 objtyp, + char *oldpassword, + char *newpassword) + +{ + uint8 key[8]; + if (0 && !ncp_17_17(key)) { + uint32 objid = ncp_17_35(name, objtyp); + if (objid) { + uint8 buff[128]; + uint8 encrypted[8]; + uint8 newcryptpasswd[16]; + int passwdx=0; + uint8 tmpid[4]; + U32_TO_BE32(objid, tmpid); + shuffle(tmpid, oldpassword, strlen(oldpassword), buff); + nw_encrypt(key, buff, encrypted); + + shuffle(tmpid, newpassword, strlen(newpassword), buff); + + if (!ncp_17_4b(encrypted, name, objtyp, passwdx, newcryptpasswd)) { + ;; + return(0); + } + } + } else { /* now we use old unencrypted algorithmus */ + if (!ncp_17_40(name, objtyp, oldpassword, newpassword)) { + ;; + return(0); + } + } + return(-1); +} + +static int do_object_login(char *name, uint16 objtyp, char *password, int option) +{ + uint8 key[8]; + if (!(option & 1) && !ncp_17_17(key)) { + uint32 objid = ncp_17_35(name, objtyp); + if (objid) { + uint8 buff[128]; + uint8 encrypted[8]; + uint8 tmpid[4]; + U32_TO_BE32(objid, tmpid); + shuffle(tmpid, password, strlen(password), buff); + nw_encrypt(key, buff, encrypted); + if (!ncp_17_18(encrypted, name, objtyp)) { + ;; + return(0); + } + } + } else { /* now we use old unencrypted algorithmus */ + if (!ncp_17_14(name, objtyp, password)) { + return(0); + } + } + return(-1); +} + +static void beep(void) +{ + fprintf(stdout, "\007"); +} + +static int get_raw_str(uint8 *s, int maxlen, int doecho) +/* returns len of readed str */ +{ + int len = 0; + while (len < maxlen){ + int key = getch(); + if (key == '\r' || key == '\n') break; + switch (key) { + case 8 : if (len) { + --len; + --s; + if (doecho) fprintf(stdout, "\010 \010"); + } else beep(); + continue; + + case '\t': beep(); + continue; + + default : *s++=(uint8)key; + len++; + break; + } /* switch */ + if (doecho) fprintf(stdout, "%c", (uint8)key); + } + *s='\0'; + return(len); +} + +static void getstr(char *what, char *str, int rsize, int doecho) +{ + fprintf(stdout, "%s: ", what); + get_raw_str(str, rsize, doecho); + fprintf(stdout, "\n"); +} + +static int login_usage(void) +{ + fprintf(stderr, "usage:\t%s [-u] [user | user password]\n", funcname); + fprintf(stderr, "\t-u : use unecrypted password\n" ); + return(-1); +} + +int func_login(int argc, char *argv[]) +{ + int result=-1; + int option=0; + uint8 uname[200]; + uint8 upasswd[200]; + + if (argc > 1) { + if (argv[1][0] == '-') { + if (argv[1][1] == 'u') option |= 1; + else return(login_usage()); + argc--; + argv++; + } + } + + if (argc > 1) strmaxcpy(uname, argv[1], sizeof(uname) -1); + else uname[0]='\0'; + if (argc > 2) strmaxcpy(upasswd, argv[2], sizeof(upasswd) -1); + else upasswd[0]='\0'; + while (result) { + if (!uname[0]) getstr("login", uname, sizeof(uname)-1, 1); + if (uname[0]) { + upstr(uname); + upstr(upasswd); + if ((result = do_object_login(uname, 0x1, upasswd, option)) < 0 && !*upasswd) { + getstr("Password", upasswd, sizeof(upasswd)-1, 0); + upstr(upasswd); + result = do_object_login(uname, 0x1, upasswd, option); + } + if (result < 0) { + fprintf(stdout, "Login incorrect\n\n"); + uname[0] = '\0'; + upasswd[0] = '\0'; + } + } else break; + } + return(result); +} + +int func_logout(int argc, char *argv[]) +{ + if (logout()) fprintf(stderr, "logout=%d", neterrno); +} + + +int func_passwd(int argc, char *argv[]) +{ + int result=0; + uint8 uname[100]; + uint8 upasswd[130]; + uint32 my_obj_id; + + if (ncp_14_46(&my_obj_id) < 0 || my_obj_id == MAX_U32 || !my_obj_id) { + fprintf(stderr, "Cannot get actual User ID\n"); + result = -1; + } + + if (!result && argc > 1) { + uint32 obj_id; + strmaxcpy(uname, argv[1], sizeof(uname) -1); + upstr(uname); + obj_id = ncp_17_35(uname, 1); + if (!obj_id) { + fprintf(stderr, "Unkwown User: %s\n", uname); + return(-1); + } + } else if (!result) { + uint16 obj_typ; + if (ncp_17_36(my_obj_id, uname, &obj_typ) || obj_typ != 1) { + fprintf(stderr, "Cannot get actual Username\n"); + result=-1; + } + } + if (!result && *uname) { + uint8 newpasswd[130]; + uint8 newpasswd2[130]; + if (my_obj_id == 1L) *upasswd='\0'; + else { + getstr("Old Password", upasswd, sizeof(upasswd)-1, 0); + upstr(upasswd); + } + getstr("New Password", newpasswd, sizeof(newpasswd)-1, 0); + getstr("New Password again", newpasswd2, sizeof(newpasswd2)-1, 0); + if (!strcmp(newpasswd, newpasswd2)) { + upstr(uname); + upstr(newpasswd); + if (do_change_object_passwd(uname, 1, upasswd, newpasswd) < 0) + result = -1; + } else { + result = -1; + fprintf(stderr, "Password misspelled\n"); + } + } + if (result < 0) fprintf(stderr, "Password not changed"); + return(result); +} + diff --git a/makefile b/makefile new file mode 100755 index 0000000..6b0f1ad --- /dev/null +++ b/makefile @@ -0,0 +1,40 @@ +# makefile DOS BCC for simple NET Client for mars_nwe. +# /**************************************************************** +# * (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * +# ****************************************************************/ + +O = .obj +E = .exe +A = .lib +S = .asm +C = .c + +INCLUDE=$(BC4)\INCLUDE +LIB=$(BC4)\LIB +CC=bcc -ml -Dmsdos -I$(INCLUDE) +LD=bcc -ml -L$(LIB) +ASFLAGS= -la -mx +AS = tasm +AR = tlib +RM = del + +ASMODS= kern$(O) +CCMODS= tools$(O) netcall$(O) ncpcall$(O) \ + login$(O) map$(O) slist$(O) nwcrypt$(O) \ + nwdebug$(O) nwtests$(O) + +all: net$(E) + +net$(E): net$(O) $(ASMODS) $(CCMODS) + $(LD) net$(O) @&&| +$(ASMODS) +$(CCMODS) +| + +$(C)$(O): + $(CC) -c $*$(C) + +$(S)$(O): + $(AS) $(ASFLAGS) $*$(S) + + diff --git a/map.c b/map.c new file mode 100755 index 0000000..841cb50 --- /dev/null +++ b/map.c @@ -0,0 +1,252 @@ +/* map.c 05-Apr-96 */ + +/**************************************************************** + * (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * + ****************************************************************/ + +#include "net.h" + +typedef struct { + uint8 connection; + uint8 volume; + uint8 buff[512]; /* complete path */ + uint8 *path; /* points to path */ +} NWPATH; + +static void show_map(uint8 *drvstr) +{ + int j; + for (j=0; j < 32; j++){ + uint8 connid; + uint8 dhandle; + uint8 flags; + if (*drvstr && (j + 'A' != *drvstr)) continue; + if ((!get_drive_info(j, &connid, &dhandle, &flags)) && flags){ + char servern[52]; + char path[256]; + if (flags & 0x80) { /* lokal DRIVE */ + path[0]= '\\'; + if (j < 2){ + strcpy(path, "DISK LW"); + } else if (getcurdir(j+1, path+1)) { + strcpy(path, "LW !OK"); + } + } else { + if (get_dir_path(dhandle, path)) { + strcpy(path, "DHANDLE !OK"); + } + } + if (connid) { + get_fs_name(connid, servern); + strcat(servern, "\\"); + } else servern[0]='\0'; + printf("MAP %c: = %s%s\n", (char)j+'A', servern, path); + } + } +} +#if 0 +static void do_map(int drive, NWPATH *nwp) +{ + if (drive > -1 && drive < 32) { + uint8 connid; + uint8 dhandle; + uint8 flags; + if ((!get_drive_info(drive, &connid, &dhandle, &flags)) && flags){ + char servern[52]; + char path[256]; + if (flags & 0x80) { /* lokal DRIVE */ + path[0]= '\\'; + if (drive < 2){ + strcpy(path, "DISK LW"); + } else if (getcurdir(drive+1, path+1)) { + strcpy(path, "LW !OK"); + } + } else { + if (get_dir_path(dhandle, path)) { + strcpy(path, "DHANDLE !OK"); + } + } + if (connid) { + get_fs_name(connid, servern); + strcat(servern, "\\"); + } else servern[0]='\0'; + printf("DOMAP %c: = %s%s\n", (char)drive+'A', servern, path); + } + } +} +#endif + +static int do_map(int drive, NWPATH *nwp) +{ + int result = -1; + if (drive > -1 && drive < 32) { + uint8 nmdrive[3]; + nmdrive[0] = drive+'A'; + nmdrive[1] = ':'; + nmdrive[2] = '\0'; + result = redir_device_drive(0x4, nmdrive, nwp->path); + } + return(result); +} + + +static int parse_argv(uint8 *drvstr, NWPATH *nwpath, + int argc, char *argv[], int smode) +{ + int k = 0; + int mode = 0; + uint8 *pd = drvstr; + *drvstr = '\0'; + memset(nwpath, 0, sizeof(NWPATH)); + *(nwpath->buff) = '\0'; + nwpath->path = nwpath->buff; + + while (++k < argc && mode > -1) { + uint8 *p = argv[k]; + while (*p && mode > -1) { + if (!mode) { + if (*p == ':') mode = -1; + else if (smode && *p != 's' && *p != 'S') mode = -1; + } + if (mode < 0) break; + else if (mode < 20) { + if (*p == ':') { + if (!mode || (mode > 1 && (*drvstr != 'S' || !smode))) + mode = -1; + else { + *pd = '\0'; + if (mode > 1) { + *drvstr='s'; + *(drvstr+1)=(uint8) atoi((char*)drvstr+1); + } + mode = 20; + pd = nwpath->buff; + } + } else { + if (++mode == 20) mode = -1; + else { + if (*p > 0x60 && *p < 0x7b) + *pd++ = *p - 0x20; /* upshift */ + else + *pd++ = *p; + } + } + } else if (mode == 20) { + if (*p == '=') mode = 30; + else if (*p != ' ' && *p != '\t') mode = -2; + } else if (mode == 30) { + if (*p != ' ' && *p != '\t') { + mode = 40; + continue; + } + } else if (mode == 40) { + if (*p > 0x60 && *p < 0x7b) + *pd++ = *p - 0x20; /* upshift */ + else + *pd++ = *p; + } + p++; + } /* while *p */ + } /* while k */ + if (mode == 30) { + getcwd((char *)nwpath->buff, sizeof(nwpath->buff)); + mode = 40; + } + if (mode && mode != 20 && mode != 40) { + fprintf(stderr, "Cannot interpret line. errcode=%d\n", mode); + return(mode < 0 ? mode : -3); + } + return(0); +} + +int func_map(int argc, char *argv[]) +{ + uint8 drvstr[22]; + NWPATH nwpath; + if (!ipx_init()) argc = 1; + if (!parse_argv(drvstr, &nwpath, argc, argv, 0)) { + if (*(nwpath.path)) { + if (do_map(*drvstr - 'A', &nwpath)< 0) + fprintf(stderr, "MAP Error\n"); + } + show_map(drvstr); + return(0); + } + return(1); +} +/* ------------------------------------------------- */ +static int show_search(uint8 *drvstr) +{ + SEARCH_VECTOR drives; + SEARCH_VECTOR_ENTRY *p=drives; + int j=0; + get_search_drive_vektor(drives); + while (p->drivenummer != 0xff && j++ < 16) { + char path[256]; + char nwname[256]; + if ( !*drvstr || j == *(drvstr+1)) { + if (p->flags && !(p->flags & 0x80)){ + get_fs_name(p->u.fs.connid, nwname); + if (get_dir_path(p->u.fs.dhandle, path)) { + strcpy(path, "ERROR NW"); + } + (void)xadd_char(nwname, '\\', 20); + } else { + nwname[0] = '\0'; + /* + nwname[0] = '<'; + strcpy(nwname+1, "LOCAL"); + */ + if (p->drivenummer == 0xfe){ + strcpy(path, p->u.d.dospath); + } else if (getcurdir((int)(p->drivenummer)+1, path)) { + strcpy(path, "ERROR DOS"); + } + /* + (void)xadd_char(nwname, '>', 20); + */ + } + strcat(nwname, path); + printf("SEARCH%2d = %c: %s\n", j, (char)(p->drivenummer)+'A', nwname); + } + p++; + } + return(0); +} + +static int set_search(uint8 *drvstr, NWPATH *nwp) +{ + 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 && (p->drivenummer + 'A' == *drvstr)) entry=j; + p++; + } + if (entry > 0) { + if (entry > 16) entry = 16; + if (--entry < j) p = drives+entry; + else (p+1)->drivenummer = 0xff; + p->drivenummer = 0xfe; + strcpy(p->u.d.dospath, nwp->path); + result = set_search_drive_vektor(drives); + } + return(result); +} + +int func_path(int argc, char *argv[]) +{ + uint8 drvstr[22]; + NWPATH nwpath; + if (!parse_argv(drvstr, &nwpath, argc, argv, 1)) { + int result=0; + if (*(nwpath.path)) result=set_search(drvstr, &nwpath); + show_search(drvstr); + return(result); + } + return(1); +} + diff --git a/mk.bat b/mk.bat new file mode 100755 index 0000000..db2def5 --- /dev/null +++ b/mk.bat @@ -0,0 +1,4 @@ +maker %1 %2 %3 %4 > err +type err +copy net.exe c:\ +del net.exe diff --git a/ncpcall.c b/ncpcall.c new file mode 100755 index 0000000..2d5da94 --- /dev/null +++ b/ncpcall.c @@ -0,0 +1,285 @@ +/* ncpcall.c 14-Mar-96 */ + +/**************************************************************** + * (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * + ****************************************************************/ + +#include "net.h" + +/* ---------------- 0x16 ----------------------------------- */ +int ncp_16_02(int dirhandle, + uint8 *path, + int *sub_dir, + uint8 *resultpath, + uint32 *creattime, + uint32 *owner_id) + +/* returns max. rights or -1 if failed */ +{ + struct { + uint16 len; + uint8 func; + uint8 dirhandle; + uint8 sub_dir[2]; + uint8 pathlen; + uint8 path[256]; + } req; + struct { + uint16 len; + uint8 sub_dir_name[16]; + uint8 create_date_time[4]; + uint8 owner_id[4]; /* HI LOW */ + uint8 max_right_mask; + uint8 reserved; /* Reserved by Novell */ + uint8 sub_dir_nmbr[2]; /* HI LOW */ + } repl = { sizeof(repl) - sizeof(uint16) }; + req.func = 0x02; + U16_TO_BE16((sub_dir) ? *sub_dir : 1, req.sub_dir); + req.dirhandle = (uint8) dirhandle; + req.pathlen = (uint8) ((path) ? strlen(path) : 0); + req.len = 5 + req.pathlen; + strmaxcpy(req.path, path, req.pathlen); + neterrno = Net_Call(0xE200, &req, &repl); + if (neterrno) return(-1); + if (resultpath) strmaxcpy(resultpath, repl.sub_dir_name, 16); + if (sub_dir) *sub_dir = GET_BE16(repl.sub_dir_nmbr); + if (creattime) *creattime = GET_BE32(repl.create_date_time); + if (owner_id) *owner_id = GET_BE32(repl.owner_id); + return((int) repl.max_right_mask); +} + +/* ---------------- 0x17 ----------------------------------- */ +int ncp_17_02(int module, int debuglevel) +/* debuglevel fuer module setzen */ +{ + struct { + uint16 len; + uint8 func; + uint8 module; + uint8 debug; + } req = { sizeof(req) - sizeof(uint16) }; + struct { + uint16 len; + uint8 olddebug; + } repl = { sizeof(repl) - sizeof(uint16) }; + req.func = 0x2; + req.module = (uint8) module; + req.debug = (uint8) debuglevel; + neterrno = Net_Call(0xE300, &req, &repl); + if (neterrno) return(-1); + return((int) repl.olddebug); +} + +int ncp_17_14(uint8 *objname, uint16 objtyp, uint8 *password) +/* login unencreypted */ +{ + struct { + uint16 len; + uint8 func; + uint8 typ[2]; + uint8 namlen; + uint8 buff[48+1+128]; + } req; + struct { + uint16 len; + } repl= { 0 }; + uint8 *p=req.buff; + req.func = 0x14; + U16_TO_BE16(objtyp, req.typ); + req.namlen = min(47, strlen(objname)); + memcpy(p, objname, req.namlen); + p += req.namlen; + *p = (uint8) min(128, strlen(password)); + req.len = 4 + req.namlen + 1 + *p; + memcpy(p+1, password, (int) *p); + neterrno = Net_Call(0xE300, &req, &repl); + if (neterrno) return(-1); + return(0); +} + +int ncp_17_17(uint8 *key) +/* get crypt key */ +{ + struct { + uint16 len; + uint8 func; + } req; + struct { + uint16 len; + uint8 key[8]; + } repl; + req.len = 1; + req.func = 0x17; + repl.len = 8; + neterrno = Net_Call(0xE300, &req, &repl); + if (neterrno) return(-1); + else { + memcpy(key, repl.key, 8); + return(0); + } +} + +int ncp_17_18(uint8 *cryptkey, uint8 *objname, uint16 objtyp) +/* keyed login */ +{ + struct { + uint16 len; + uint8 func; + uint8 key[8]; + uint8 typ[2]; + uint8 namlen; + uint8 name[48]; + } req; + struct { + uint16 len; + } repl={ 0 }; + req.len = sizeof(req) - sizeof(uint16); + req.func = 0x18; + U16_TO_BE16(objtyp, req.typ); + req.namlen = min(sizeof(req.name), strlen(objname)); + memcpy(req.key, cryptkey, 8); + memcpy(req.name, objname, (int) req.namlen); + neterrno = Net_Call(0xE300, &req, &repl); + if (neterrno) return(-1); + return(0); +} + +uint32 ncp_17_35(uint8 *objname, uint16 objtyp) +/* get bindery object id */ +{ + struct { + uint16 len; + uint8 func; + uint8 typ[2]; + uint8 namlen; + uint8 name[48]; + } req; + struct { + uint16 len; + uint8 object_id[4]; + uint8 object_type[2]; + uint8 object_name[48]; + } repl; + req.len = sizeof(req) - sizeof(uint16); + repl.len = sizeof(repl) - sizeof(uint16); + req.func = 0x35; + U16_TO_BE16(objtyp, req.typ); + req.namlen = min(sizeof(req.name), strlen(objname)); + memcpy(req.name, objname, (int) req.namlen); + neterrno = Net_Call(0xE300, &req, &repl); + if (neterrno) return(0L); + strmaxcpy(objname, repl.object_name, 47); + return(GET_BE32(repl.object_id)); +} + +int ncp_17_36(uint32 obj_id, uint8 *objname, uint16 *objtyp) +/* get bindery object name */ +{ + struct { + uint16 len; + uint8 func; + uint8 id[4]; + } req; + struct { + uint16 len; + uint8 object_id[4]; + uint8 object_type[2]; + uint8 object_name[48]; + } repl; + req.len = sizeof(req) - sizeof(uint16); + repl.len = sizeof(repl) - sizeof(uint16); + req.func = 0x36; + U32_TO_BE32(obj_id, req.id); + neterrno = Net_Call(0xE300, &req, &repl); + if (neterrno) return(-1); + if (objname) strmaxcpy(objname, repl.object_name, 47); + if (objtyp) *objtyp = GET_BE16(repl.object_type); + return(0); +} + + +int ncp_17_40(uint8 *objname, uint16 objtyp, + uint8 *password, uint8 *newpassword) +/* change password unencreypted */ +{ + struct { + uint16 len; + uint8 func; + uint8 typ[2]; + uint8 namlen; + uint8 buff[48+1+128+1+128]; + } req; + struct { + uint16 len; + } repl = { 0 }; + uint8 *p=req.buff; + req.func = 0x40; + U16_TO_BE16(objtyp, req.typ); + req.namlen = min(47, strlen(objname)); + memcpy(p, objname, req.namlen); + p += req.namlen; + *p = (uint8) min(128, strlen(password)); + req.len = 4 + req.namlen + 1 + *p; + memcpy(p+1, password, (int) *p); + p += (1 + *p); + *p = (uint8) min(128, strlen(newpassword)); + req.len += (1 + *p); + memcpy(p+1, newpassword, (int) *p); + neterrno = Net_Call(0xE300, &req, &repl); + if (neterrno) return(-1); + return(0); +} + +int ncp_14_46(uint32 *obj_id) +/* get bindery access level & actual ID */ +{ + struct { + uint16 len; + uint8 func; + } req; + struct { + uint16 len; + uint8 access; + uint8 id[4]; + } repl; + req.len = 1; + req.func = 0x46; + repl.len = 5; + neterrno = Net_Call(0xE300, &req, &repl); + if (neterrno) return(-1); + else { + if (obj_id) *obj_id = GET_BE32(repl.id); + return(repl.access); + } +} + + +int ncp_17_4b(uint8 *cryptkey, uint8 *objname, uint16 objtyp, + int passwx, uint8 *newpassword) +/* keyed change password */ +{ + struct { + uint16 len; + uint8 func; + uint8 key[8]; + uint8 typ[2]; + uint8 namlen; + uint8 buff[48+1+16]; + } req; + struct { + uint16 len; + } repl = { 0 }; + uint8 *p = req.buff; + req.func = 0x4b; + memcpy(req.key, cryptkey, 8); + U16_TO_BE16(objtyp, req.typ); + req.namlen = (uint8) min(48, strlen(objname)); + req.len = 12 + req.namlen + 1 + 16; + memcpy(p, objname, (int) req.namlen); + p += req.namlen; + *p++ = (uint8) passwx; + memcpy(p, newpassword, 16); + neterrno = Net_Call(0xE300, &req, &repl); + if (neterrno) return(-1); + return(0); +} diff --git a/net.c b/net.c new file mode 100755 index 0000000..8ee55cd --- /dev/null +++ b/net.c @@ -0,0 +1,74 @@ +/* net.c 14-Mar-96 */ +/* simple client programm to act with mars_nwe */ + +/**************************************************************** + * (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * + ****************************************************************/ + +#include "net.h" +char *funcname=NULL; +typedef int (*NET_FUNC)(int argc, char *argv[]); + +static struct s_net_functions { + char *name; + char *description; + NET_FUNC func; +} net_functions[] = { +{"LOGIN", "login to Server as User" , func_login }, +{"MAP", "list maps and map drives" , func_map }, +{"PATH", "list and set search path" , func_path }, +{"LOGOUT", "logout from Server", func_logout }, +#if 0 +{"SLIST", "list Servers", func_slist }, +#endif +{"PASSWD", "change password", func_passwd }, +#if 1 +{"TESTS", "only testroutines!", func_tests }, +#endif +{"DEBUG", "set debug level, for mars_nwe only !", func_debug } +}; + +#define MAX_FUNCS (sizeof(net_functions) / sizeof(struct s_net_functions)) + +int main(int argc, char *argv[]) +{ + NET_FUNC func = NULL; + int result = -1; + if (argc > 1) { + char funcn[200]; + int k= MAX_FUNCS; + strmaxcpy(funcn, argv[1], sizeof(funcn)-1); + upstr(funcn); + while (k--) { + if (!strcmp(funcn, net_functions[k].name)) { + func=net_functions[k].func; + funcname=net_functions[k].name; + break; + } + } + } + if (func != NULL) { + if (ipx_init() || func == func_map) { + result = (*func) (argc-1, &(argv[1])); + } + } else { + int k= MAX_FUNCS; + char progname[256]; + strmaxcpy(progname, argv[0], sizeof(progname)-1); + upstr(progname); + fprintf(stderr, "\n" + "****************************************************************\n" + "* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *\n" + "****************************************************************\n\n" ); + fprintf(stderr, "Usage:\t%s func ... \nfuncs:", progname); + while (k--) { + if (net_functions[k].func) { + fprintf(stderr, "\t%s\t: %s\n", + net_functions[k].name, net_functions[k].description); + } + } + } + return(result); +} + + diff --git a/net.exe b/net.exe new file mode 100755 index 0000000..77dd44a Binary files /dev/null and b/net.exe differ diff --git a/net.h b/net.h new file mode 100755 index 0000000..54cf5f6 --- /dev/null +++ b/net.h @@ -0,0 +1,202 @@ +/* net.h: 01-Feb-96 */ + +/**************************************************************** + * (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * + ****************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef unsigned int UI; +typedef unsigned char UC; +typedef unsigned char uint8; +typedef unsigned short int uint16; +typedef unsigned long int uint32; + +typedef union REGS REGS; +typedef struct SREGS SREGS; + +typedef void (*FUNC_VOID)(); +typedef int (*FUNC_INT)(); + + +typedef struct { + uint8 checksum[2]; + uint16 packetlen; + uint8 tcontrol; + uint8 ptype; + uint8 dest_net[4]; + uint8 dest_node[6]; + uint16 dest_sock; /* HI LOW */ + uint8 source_net[4]; + uint8 source_node[6]; + uint16 source_sock; /* HI LOW */ +} IPX_HEADER; + +typedef struct { + uint8 *link_address; + FUNC_VOID esr_routine; + uint8 in_use_flag; + uint8 completition_code; + uint16 socket; /* HI LOW */ + uint8 ipx_workspace[4]; /* interner Gebrauch */ + uint8 drv_workspace[4]; /* interner Gebrauch */ + uint8 immediate_address[6]; /* HI LOW Node Address */ + uint16 fragment_count; /* Anzahl Fragment Buffers */ + uint8 *fragment_1; + uint16 fragment_1_size; + /* K”nnen auch mehr sein */ +} ECB; + +#include "kern.h" + +#define UI2NET(i) ( ( (i) << 8) | ( ((i)>>8) & 0xFF) ) +#define NET2UI(i) ( ( (i) << 8) | ( ((i)>>8) & 0xFF) ) + +#define U16_TO_BE16(u, b) { uint16 a=(u); \ + *( (uint8*) (b) ) = *( ((uint8*) (&a)) +1); \ + *( ((uint8*) (b)) +1) = *( (uint8*) (&a)); } + + +#define U32_TO_BE32(u, ar) { uint32 a= (u); uint8 *b= ((uint8*)(ar))+3; \ + *b-- = (uint8)a; a >>= 8; \ + *b-- = (uint8)a; a >>= 8; \ + *b-- = (uint8)a; a >>= 8; \ + *b = (uint8)a; } + +#define U16_TO_16(u, b) { uint16 a=(u); memcpy(b, &a, 2); } +#define U32_TO_32(u, b) { uint32 a=(u); memcpy(b, &a, 4); } + +#define GET_BE16(b) ( (int) *(((uint8*)(b))+1) \ + | ( ( (int) *( (uint8*)(b) ) << 8) ) ) + +#define GET_BE32(b) ( (uint32) *(((uint8*)(b))+3) \ + | ( ((uint32) *(((uint8*)(b))+2) ) << 8) \ + | ( ((uint32) *(((uint8*)(b))+1) ) << 16) \ + | ( ((uint32) *( (uint8*)(b) ) ) << 24) ) + + +#define GET_16(b) ( (int) *( (uint8*)(b) ) \ + | ( ( (int) *(((uint8*)(b))+1) << 8) ) ) + +#define GET_32(b) ( (uint32) *( (uint8*)(b) ) \ + | ( ((uint32) *(((uint8*)(b))+1) ) << 8) \ + | ( ((uint32) *(((uint8*)(b))+2) ) << 16) \ + | ( ((uint32) *(((uint8*)(b))+3) ) << 24) ) + +#define MAX_U32 ((uint32)0xffffffffL) +#define MAX_U16 ((uint16)0xffff) + +#define NWSERV 1 +#define NCPSERV 2 +#define NWCONN 3 +#define NWCLIENT 4 +#define NWBIND 5 + +/* net.c */ +extern char *funcname; + +/* tools.c */ +extern void clear_kb(void); +extern int key_pressed(void); +extern int ask_user(char *p, ...); +extern int strmaxcpy(char *dest, char *source, int len); +extern char *xadd_char(char *s, int c, int maxlen); +extern uint8 *upstr(uint8 *s); + +#define add_char(s, c) xadd_char((s), (c), -1) + +extern char *getglobenv(char *option); +extern int putglobenv(char *option); + +/* NETCALLS */ +#define DRIVE_ADD 1 +#define DRIVE_INSERT 2 +#define DRIVE_DELETE 3 + +typedef struct { + uint8 drivenummer; /* 0xff, 0xfe fr DOSPATH mit Pfad */ + uint8 flags; + union { + struct { + char dospath[65]; + } d; + struct fs { + uint8 connid; + uint8 dhandle; + } fs; + } u; +} SEARCH_VECTOR_ENTRY; + +typedef SEARCH_VECTOR_ENTRY SEARCH_VECTOR[17]; + +extern int neterrno; + +#define alloc_permanent_dir_handle(dhandle, path, drive, rights) \ + alloc_dir_handle(0x12, (dhandle), (path), (drive), (rights)) + +#define alloc_temp_dir_handle(dhandle, path, drive, rights) \ + alloc_dir_handle(0x13, (dhandle), (path), (drive), (rights)) + +extern int ipx_init(void); + +extern int alloc_dir_handle(int func, int dhandle, char *path, + int driveletter, uint8 *effrights); + +extern int dealloc_dir_handle(int dhandle); + +extern int get_dir_path(uint8 dhandle, char *path); +extern int get_volume_name(uint8 nr, char *name); + +extern int get_search_drive_vektor(SEARCH_VECTOR_ENTRY *vec); +extern int set_search_drive_vektor(SEARCH_VECTOR_ENTRY *vec); + +/********* ncpcall.h ***********/ +extern int ncp_16_02(int dirhandle, + uint8 *path, + int *sub_dir, + uint8 *resultpath, + uint32 *creattime, + uint32 *owner_id); + +extern int ncp_17_02(int module, int debuglevel); +extern int ncp_17_14(uint8 *objname, uint16 objtyp, uint8 *password); +extern int ncp_17_17(uint8 *key); +extern int ncp_17_18(uint8 *cryptkey, uint8 *objname, uint16 objtyp); +extern uint32 ncp_17_35(uint8 *objname, uint16 objtyp); +extern int ncp_17_40(uint8 *objname, uint16 objtyp, uint8 *password, + uint8 *newpassword); + +extern int ncp_17_4b(uint8 *cryptkey, uint8 *objname, uint16 objtyp, + int passwx, uint8 *newpassword); + +/* map.c */ +extern int func_map(int argc, char *argv[]); +extern int func_path(int argc, char *argv[]); + +/* login.c */ +extern int func_login(int argc, char *argv[]); +extern int func_logout(int argc, char *argv[]); +extern int func_passwd(int argc, char *argv[]); + +/* slist.c */ +extern int func_slist(int argc, char *argv[]); + +/* nwdebug.c */ +extern int func_debug(int argc, char *argv[]); + +/* nwtests.c */ +extern int func_tests(int argc, char *argv[]); + + + + diff --git a/netcall.c b/netcall.c new file mode 100755 index 0000000..25fc654 --- /dev/null +++ b/netcall.c @@ -0,0 +1,408 @@ +/* netcall.c: 05-Apr-96 */ + +/**************************************************************** + * (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * + ****************************************************************/ + +#include "net.h" + +int neterrno=0; + +int ipx_init(void) +{ +static int ipx_is_init=0; +static int ipx_is_ok =0; + if (!ipx_is_init) { + ipx_is_init++; + ipx_is_ok = IPXinit(); + } + return(ipx_is_ok); +} + +static void *get_shell_ptr(uint16 func) +{ + if (ipx_init()) { + void *p = NULL; + REGS regs; + SREGS sregs; + regs.x.ax = func; + if (!(intdosx(®s, ®s, &sregs) & 0xff)) + p = MK_FP(sregs.es, regs.x.si); + return(p); + } else return(NULL); +} + +int detach(int servernmbr) +{ + REGS regsin, regsout; + regsin.x.ax = 0xf101; + regsin.x.dx = servernmbr; + return(intdos(®sin, ®sout) & 0xff); +} + +int logout(void) +{ + REGS regsin, regsout; + regsin.x.ax = 0xd700; + return(intdos(®sin, ®sout) & 0xff); +} + +int redir_device_drive(int devicetyp, uint8 *devname, uint8 *remotename) +/* if devicetyp == -1, the redir is canceled */ +{ + REGS regs; + SREGS sregs; + int result; + uint8 buff1[16]; + uint8 buff2[128]; + uint8 *ldevname = buff1; + uint8 *lremotename = buff2; + strncpy(ldevname, devname, 16); + regs.x.ax = (devicetyp == -1) ? 0x5f04 : 0x5f03; + regs.h.bl = (uint8)devicetyp; + regs.x.cx = 0x574e; /* user sign 'NW' */ + sregs.ds = FP_SEG(ldevname); + regs.x.si = FP_OFF(ldevname); + if (devicetyp > -1) { + strncpy(lremotename, remotename, 128); + sregs.es = FP_SEG(lremotename); + regs.x.di = FP_OFF(lremotename); + } + result = intdosx(®s, ®s, &sregs); + return(regs.x.cflag ? -result : 0); +} + +int list_redir(int index, int *devicetyp, uint8 *devname, uint8 *remotename) +{ + REGS regs; + SREGS sregs; + int result; + uint8 buff1[16]; + uint8 buff2[128]; + uint8 *ldevname = buff1; + uint8 *lremotename = buff2; + memset(ldevname, 0, sizeof(buff1)); + memset(lremotename, 0, sizeof(buff2)); + regs.x.ax = 0x5f02; + regs.x.bx = index; + regs.x.cx = 0x574e; /* user sign 'NW' */ + sregs.ds = FP_SEG(ldevname); + regs.x.si = FP_OFF(ldevname); + sregs.es = FP_SEG(lremotename); + regs.x.di = FP_OFF(lremotename); + result = intdosx(®s, ®s, &sregs); + if (!regs.x.cflag) { + if (devname) strcpy(devname, ldevname); + if (remotename) strcpy(remotename, lremotename); + if (devicetyp) *devicetyp = (int)regs.h.bl; + return((int)regs.h.bh); + } else return(-result); +} + +int get_drive_info(uint8 drivenumber, uint8 *connid, + uint8 *dhandle, uint8 *statusflags) + +/* drivenumber 0 .. 31 */ +{ + uint8 *drive_handle_table = get_shell_ptr(0xef00); + uint8 *drive_flag_table = get_shell_ptr(0xef01); + uint8 *drive_conn_table = get_shell_ptr(0xef02); + + if ( !drive_handle_table + || !drive_flag_table + || !drive_conn_table + || drivenumber > 31) { + char path[100]; + if (drivenumber < 2 || !getcurdir(drivenumber+1, path)) { + *dhandle = 0; + *connid = 0; + *statusflags = 0x80; + return(0); + } + return(-1); + } + *dhandle = *(drive_handle_table+ drivenumber); + *connid = *(drive_conn_table + drivenumber); + *statusflags = *(drive_flag_table + drivenumber); + return(0); +} + +typedef struct { + char fsname[8][48]; +} SERVER_NAME_TABLE; + +int get_fs_name(int connid, char *name) +/* Connection 1 .. 8 */ +{ + SERVER_NAME_TABLE *sf_t = get_shell_ptr(0xef04); + if (sf_t && connid > 0 && connid-- < 8){ + strmaxcpy(name, sf_t->fsname[connid], 48); + return(0); + } + name[0] = '\0'; + return(-11); +} + +static char *path_env_name="PATH"; + +int get_search_drive_vektor(SEARCH_VECTOR_ENTRY *vec) +/* maximal 16 Entries */ +{ + char *path=getglobenv(path_env_name); + SEARCH_VECTOR_ENTRY *v = vec; + int anz=0; + v->drivenummer = 0xff; + if (path){ + while (*path && anz++ < 16){ + char *p1 = path; + int len = 0; + while (*path && *path++ !=';') len++; + if (*(p1+1) == ':' + && *p1 >= 'A' && *p1 <= 'Z' && + (len==2 || (len == 3 && *(p1+2) == '.'))) { + v->drivenummer = *p1 - 'A'; + get_drive_info(v->drivenummer, &(v->u.fs.connid), + &(v->u.fs.dhandle), &(v->flags)); + } else { + v->flags = 0; + v->drivenummer = 0xfe; /* ergibt ? */ + strmaxcpy(v->u.d.dospath, p1, len); + } + (++v)->drivenummer = 0xff; + if (*path == ';') path++; + } + } + return(0); +} + +int set_search_drive_vektor(SEARCH_VECTOR_ENTRY *vec) +{ + char path[256]; + char *p=path; + SEARCH_VECTOR_ENTRY *v; + int plen=strlen(path_env_name); + strcpy(path, path_env_name); + path[plen] = '='; + path[++plen] = '\0'; + while ((NULL != (v = vec++)) && v->drivenummer != 0xff){ + if (p > path) *p++=';'; + else p+=plen; + if (v->drivenummer < 26) { + *p++ = (char) v->drivenummer + 'A'; + *p++ = ':'; + *p++ = '.'; + *p = '\0'; + } else { + strcpy(p, v->u.d.dospath); + p+= strlen(v->u.d.dospath); + } + } + return(putglobenv(path)); +} + +int alloc_dir_handle(int func, + int dhandle, + char *path, + int driveletter, + uint8 *effrights) +{ + int pathlen = (path == NULL) ? 0 : strlen(path); + struct { + uint16 len; + uint8 func; + uint8 dhandle; + uint8 drive; + uint8 pathlen; + uint8 path[256]; + } req; + struct { + uint16 len; + uint8 newhandle; + uint8 effrights; + } repl; + req.func = (uint8)func; + req.dhandle = (uint8)dhandle; + req.drive = (uint8)driveletter; + req.pathlen = (uint8)pathlen; + xmemmove(req.path, path, pathlen); + req.len = 4 + pathlen; + repl.len = 2; +/* + printf("alloc_dir_handle, path=%s, len=%d, disk=%c\n", path, pathlen, driveletter); +*/ + neterrno = Net_Call(0xE200, &req, &repl); + fprintf(stderr, "neterrno=%d\n", neterrno); + if (neterrno && neterrno != 0xff) return(-1); + + if (effrights) *effrights = repl.effrights; + return((int)repl.newhandle); +} + +int dealloc_dir_handle(int dhandle) +{ + struct { + uint16 len; + uint8 func; + uint8 dhandle; + } req; + struct { + uint16 len; + } repl; + req.len = 2; + req.func = 0x14; + req.dhandle = (uint8)dhandle; + repl.len = 0; + neterrno = Net_Call(0xE200, &req, &repl); + if (neterrno) return(-1); + else return(0); +} + +int set_dir_path(uint8 desthandle, uint8 handle, char *path) +/* Set Directory Handle */ +{ + struct { + uint16 len; + uint8 func; + uint8 desth; + uint8 sourceh; + uint8 pathlen; + uint8 path[256]; + } req; + struct { + uint16 len; + } repl; + req.pathlen = (path) ? strlen(path) : 0; + if (req.pathlen) memcpy(req.path, path, (int)req.pathlen); + req.len = 4+req.pathlen; + req.func = 0; + req.sourceh = handle; + req.desth = desthandle; + repl.len = 0; + neterrno = Net_Call(0xE200, &req, &repl); + return( (neterrno) ? -1 : 0); +} + +int get_dir_path(uint8 dhandle, char *path) +{ + struct { + uint16 len; + uint8 data[2]; + } req; + struct { + uint16 len; + uint8 pathlen; + uint8 path[255]; + } repl; + req.len = 2; + req.data[0] = 0x1; + req.data[1] = dhandle; + repl.len = 256; + neterrno = Net_Call(0xE200, &req, &repl); + if (neterrno) return(-1); + else { + strmaxcpy(path, repl.path, (int)repl.pathlen); + return(0); + } +} + +int get_volume_name(uint8 nr, char *name) +{ + struct { + uint16 len; + uint8 func; + uint8 nr; + } req; + struct { + uint16 len; + uint8 namlen; + uint8 name[16]; + } repl; + req.len = 2; + req.func = 0x6; + req.nr = nr; + repl.len = 17; + neterrno = Net_Call(0xE200, &req, &repl); + if (neterrno) return(-1); + else { + strmaxcpy(name, repl.name, (int)repl.namlen); + return(0); + } +} + + +int save_dir_handle(uint8 dhandle, uint8 *savebuffer) +{ + struct { + uint16 len; + uint8 func; + uint8 dhandle; + } req; + struct { + uint16 len; + uint8 savebuffer[16]; + } repl; + req.len = 2; + req.func = 0x17; + req.dhandle = dhandle; + repl.len = 16; + neterrno = Net_Call(0xE200, &req, &repl); + if (neterrno) return(-1); + else { + xmemmove(savebuffer, repl.savebuffer, 16); + return(0); + } +} + +int restore_dir_handle(uint8 *savebuffer, uint8 *dhandle, uint8 *effrights) +{ + struct { + uint16 len; + uint8 func; + uint8 savebuffer[16]; + } req; + struct { + uint16 len; + uint8 dhandle; + uint8 effrights; + } repl; + req.len = 17; + req.func = 0x18; + repl.len = 2; + xmemmove(req.savebuffer, savebuffer, 16); + neterrno = Net_Call(0xE200, &req, &repl); + if (neterrno) return(-1); + else { + *dhandle = repl.dhandle; + *effrights = repl.effrights; + return(0); + } +} + + + + + + + + + + +int mapdrive(uint8 connection, uint8 dhandle, char *path, + uint8 searchflag, uint8 searchorder, + uint8 *driveletter, uint8 *newdhandle, uint8 *effrights) + +/* Searchorder 0 normal Drive; 1..16 Searchdrives */ +/* searchflag only if Searchdrive : */ +/* DRIVE_ADD, DRIVE_INSERT, DRIVE_DELETE */ +{ + + + return(-1); +} + + + + + + + diff --git a/nwcrypt.c b/nwcrypt.c new file mode 100755 index 0000000..507ce54 --- /dev/null +++ b/nwcrypt.c @@ -0,0 +1,213 @@ +/*$********************************************************* +$* +$* This code has been taken from DDJ 11/93, from an +$* article by Pawel Szczerbina. +$* +$* Password encryption routines follow. +$* Converted to C from Barry Nance's Pascal +$* prog published in the March -93 issue of Byte. +$* +$* Adapted to be useable for ncpfs by +$* Volker Lendecke in +$* October 1995. +$* +$* Stolen to be useable for mars_nwe by +$* Martin Stover in +$* Dezember 1995. +$**********************************************************/ + +/**************************************************************************** + +I read that Novell is not very open when it comes to technical details +of the Netware Core Protocol. This might be especially true for the +encryption stuff. I took the necessary code from Dr. Dobb's Journal +11/93, Undocumented Corner. I asked Jon Erickson about +the legal status of this piece of code: + + +--- +Date: Thu, 12 Oct 1995 13:44:18 +0100 +From: Volker Lendecke +To: jon@ddj.com +Subject: legal status of your source code? + + +Hello! + +I hope that you're the right one to write to, you are the first on your WWW +server. If you are not, could you please forward this message to the right +person? Thanks. + +I'm currently exploring the possibility to write a free (in the GNU GPL +sense) NCP filesystem, which would allow me to access a novell server +transparently. For that I would like to use the encryption functions you +published in DDJ 11/93, Undocumented Corner. I would make some cosmetic +changes, such as other indentations, minor code changes and so on. But I do +not know if that allows me to publish this code under GPL. One alternative +would be to publish a diff against your listing, but that would probably +contain much of your code as well, and it would be very inconvenient for +the average user. + +I think that you have some kind of standard procedure for such a +case. Please tell me what I should do. + +Many thanks in advance, + + Volker + + +=================================================================+ + ! Volker Lendecke Internet: lendecke@namu01.gwdg.de ! + ! D-37081 Goettingen, Germany ! + +=================================================================+ + +-- + + +I got the following answer: + +--- +From: Jon Erickson +X-Mailer: SCO System V Mail (version 3.2) +To: lendecke@namu01.gwdg.de +Subject: Re: legal status of your source code? +Date: Thu, 12 Oct 95 5:42:56 PDT + +Volker, +Code from Dr. Dobb's Journal related articles is provided for +anyone to use. Clearly, the author of the article should be +given credit. +Jon Erickson + +--- + +With this answer in mind, I took the code and made it a bit more +C-like. The original seemed to be translated by a mechanical pascal->c +translator. Jon's answer encouraged me to publish nwcrypt.c under the +GPL. If anybody who knows more about copyright and sees any problems +with this, please tell me. +****************************************************************************/ + +/******************* Data types ***************************/ +typedef unsigned char buf32[32]; +typedef unsigned char buf16[16]; +typedef unsigned char buf8[8]; +typedef unsigned char buf4[4]; +typedef unsigned char u8; + +static u8 encrypttable[256] = +{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8, + 0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9, + 0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6, + 0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0, + 0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD, + 0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE, + 0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7, + 0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1, + 0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4, + 0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2, + 0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3, + 0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0, + 0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8, + 0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3, + 0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0, + 0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD}; + +static buf32 encryptkeys = +{0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D, + 0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35, + 0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11, + 0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0}; + +#include "nwcrypt.h" +static void +shuffle1(buf32 temp, unsigned char *target) +{ + short b4; + unsigned char b3; + int s, b2, i; + + b4 = 0; + + for (b2 = 0; b2 <= 1; ++b2) + { + for (s = 0; s <= 31; ++s) + { + b3 = (temp[s]+b4) ^ (temp[(s+b4)&31] - encryptkeys[s]); + b4 = b4 + b3; + temp[s] = b3; + } + } + + for (i = 0; i <= 15; ++i) { + target[i] = encrypttable[temp[ 2*i ]] + | (encrypttable[temp[ 2*i + 1]] << 4); + } +} + + +void +shuffle(unsigned char *lon, const unsigned char *buf, int buflen, + unsigned char *target) +{ + int b2, d, s; + buf32 temp; + + while ( (buflen > 0) + && (buf[buflen - 1] == 0)) { + buflen = buflen - 1; + } + + for (s = 0; s < 32; s++) { + temp[s] = 0; + } + + d = 0; + while (buflen >= 32) + { + for (s = 0; s <= 31; ++s) + { + temp[s] = temp[s] ^ buf[d]; + d = d + 1; + } + buflen = buflen - 32; + } + b2 = d; + if (buflen > 0) + { + for (s = 0; s <= 31; ++s) + { + if (d + buflen == b2) + { + b2 = d; + temp[s] = temp[s] ^ encryptkeys[s]; + } else { + temp[s] = temp[s] ^ buf[b2]; + b2 = b2 + 1; + } + } + } + + for (s = 0; s <= 31; ++s) + temp[s] = temp[s] ^ lon[s & 3]; + + shuffle1(temp,target); +} + + +void +nw_encrypt(unsigned char *fra,unsigned char *buf,unsigned char *til) +{ + buf32 k; + int s; + + shuffle(&(fra[0]), buf, 16, &(k[ 0])); + shuffle(&(fra[4]), buf, 16, &(k[16])); + + for (s = 0; s <= 15; ++s) + k[s] = k[s] ^ k[31 - s]; + + for (s = 0; s <= 7; ++s) + til[s] = k[s] ^ k[15 - s]; +} + + diff --git a/nwcrypt.h b/nwcrypt.h new file mode 100755 index 0000000..3876b0b --- /dev/null +++ b/nwcrypt.h @@ -0,0 +1,7 @@ +/* nwcrypt.h */ +extern void shuffle(unsigned char *lon, + const unsigned char *buf, int buflen, + unsigned char *target); + +extern void nw_encrypt(unsigned char *fra, + unsigned char *buf,unsigned char *til); diff --git a/nwdebug.c b/nwdebug.c new file mode 100755 index 0000000..a1f9c56 --- /dev/null +++ b/nwdebug.c @@ -0,0 +1,36 @@ +/* nwdebug.c 04-Apr-96 */ + +/**************************************************************** + * (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * + ****************************************************************/ + +#include "net.h" + +static int usage(void) +{ + fprintf(stderr, "usage:\t%s NCPSERV|NWCONN|NWBIND level\n", funcname); + fprintf(stderr, "\tlevel=0 .. 99\n" ); + return(-1); +} + +int func_debug(int argc, char *argv[]) +{ + uint8 s[200]; + int module; + int level; + int result; + if (argc < 3) return(usage()); + strmaxcpy(s, argv[1], sizeof(s) -1); + upstr(s); + if (!strcmp(s, "NCPSERV")) module=NCPSERV; + else if (!strcmp(s, "NWCONN" )) module=NWCONN; + else if (!strcmp(s, "NWBIND" )) module=NWBIND; + else return(usage()); + level = atoi(argv[2]); + if (level < 0 || level > 99) return(usage()); + result = ncp_17_02(module, level); + if (result < 0) fprintf(stderr, "set debug failed\n"); + else fprintf(stdout, "Debug level for %s changed from %d to %d\n", + s, result, level); + return(result < 0 ? result : 0); +} diff --git a/nwtests.c b/nwtests.c new file mode 100755 index 0000000..52c8fed --- /dev/null +++ b/nwtests.c @@ -0,0 +1,46 @@ +/* nwtests.c 14-Mar-96 */ + +/**************************************************************** + * (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * + ****************************************************************/ + +#include "net.h" + +static int usage(void) +{ + fprintf(stderr, "usage:\t%s NCPSERV|NWCONN level\n", funcname); + fprintf(stderr, "\tlevel=0 .. 99\n" ); + return(-1); +} + +int func_tests(int argc, char *argv[]) +{ + int level = ncp_17_02(NWCONN, 6); + int dirhandle = alloc_temp_dir_handle(0, "SYS:", 'd', NULL); + int result = -1; + uint8 *path = (argc < 2) ? "SYS:\\TMP" : argv[1]; + if (dirhandle > -1) { + result = ncp_16_02(dirhandle, "SYSTEM/", NULL, NULL, NULL, NULL); + result = ncp_16_02(dirhandle, "SYSTEM", NULL, NULL, NULL, NULL); + } + fprintf(stdout, "dirhandle=%d, result=%d\n", dirhandle, result); + result = redir_device_drive(0x4, "u:", path); + fprintf(stdout, "redir path=%s, result=%d\n", path, result); + + path="Q1"; + result = redir_device_drive(0x3, "LPT1", path); + fprintf(stdout, "redir path=%s, result=%d\n", path, result); + + { + int k =-1; + uint8 devname[20]; + uint8 remotename[130]; + int devicetyp; + while ((result = list_redir(++k, &devicetyp, devname, remotename)) > -1){ + fprintf(stdout, "index=%d, dev=%s(%d), %s result=%d\n", + k, devname, devicetyp, remotename, result); + } + } + if (level > -1) (void) ncp_17_02(NWCONN, level); + return(0); +} diff --git a/slist.c b/slist.c new file mode 100755 index 0000000..d046816 --- /dev/null +++ b/slist.c @@ -0,0 +1,15 @@ +/* map.c 12-Jan-96 */ + +/**************************************************************** + * (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * + ****************************************************************/ + +#include "net.h" + +int func_slist(int argc, char *argv[]) +{ + + + + +} diff --git a/teste.c b/teste.c new file mode 100755 index 0000000..7d6711e --- /dev/null +++ b/teste.c @@ -0,0 +1,95 @@ +int main() +{ + char *fn="F.$LN"; + char *string="ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz"; + int result; + struct stat stbuff; + long offset; + char buff[1024]; + char readbuff[500]; + int j; + int fd=creatnew(fn, S_IREAD |S_IWRITE); + if (fd > -1) { + printf("Konnte Date erzeugen\n"); + close(fd); + } else { + printf("Konnte Datei nicht erzeugen\n"); + } + fd = open(fn, O_RDWR|O_CREAT|O_TRUNC|O_DENYNONE, 0666); + memset(buff, 0, sizeof(buff) ); + strcpy(buff, string); + write(fd, buff, strlen(buff)); + close(fd); + _chmod(fn, 1, _chmod(fn, 0) | 0x80 ); + stat(fn, &stbuff); + printf("Filesize ber stat =%ld\n", stbuff.st_size); + fd = open(fn, O_RDWR | O_BINARY |O_DENYNONE); + + offset = lseek(fd, 0L, SEEK_END); + printf("Filesize ber lseek =%ld\n", offset); + write(fd, buff, strlen(buff)); + + lseek(fd, 0L, SEEK_SET); + for (j=0; j < strlen(buff)*2; j++){ + read(fd, readbuff, 1); + printf("BUFF = %c\n", readbuff[0]); + } + lseek(fd, 1L, SEEK_SET); + for (j = 0; j < 20; j++){ + write(fd, buff+j, 1); + } + + for (j=0; j <60; j++){ + lseek(fd, (long) j, SEEK_SET); + read(fd, readbuff, 2); + printf("BUFF = %c, %c \n", readbuff[0], readbuff[1]); + } + + lseek(fd, 10L, SEEK_SET); + read(fd, buff, 1); + printf("BUFF[10] = %c\n", buff[0]); + result=lock(fd, 100L, 1L); + printf("lock result = %d\n", result); + result=unlock(fd, 100L, 1L); + printf("unlock result = %d\n", result); + close(fd); + + fd = open(fn, O_BINARY|O_RDWR|O_CREAT|O_TRUNC|O_DENYNONE, 0666); + if (fd > -1) { + int bufflen; + strcpy(buff, "d:..\\marlib\\c0l.obj+"); + strcat(buff, "\r\n"); + strcat(buff, "x"); + strcat(buff, "\r\n"); + strcat(buff, "x"); + strcat(buff, "\r\n"); + strcat(buff, "/c/x"); + strcat(buff, "\r\n"); + strcat(buff, "d:..\\marlib\\EMU.LIB+"); + strcat(buff, "\r\n"); + strcat(buff, "d:..\\marlib\\mathl.lib+"); + strcat(buff, "\r\n"); + strcat(buff, "d:..\\marlib\\cl.lib"); + bufflen=strlen(buff); + printf("bufflen = %d, buff=%s\n", bufflen, buff); + write(fd, buff, bufflen); + close(fd); + fd = open(fn, O_TEXT|O_RDONLY); + if (fd > -1) { + char *p=readbuff; + int anz = 0; + memset(readbuff, 0, sizeof(readbuff) ); + while (read(fd, p, 1) == 1){ + anz++; + p++; + } + printf("read = %d, buff=%s\n", anz, readbuff); + close(fd); + } + } + /* + result = detach(1); + printf("Detach result=0x%x", result); + */ + return(0); +} diff --git a/tools.c b/tools.c new file mode 100755 index 0000000..65ca658 --- /dev/null +++ b/tools.c @@ -0,0 +1,201 @@ +/* tools.c: 12-Jan-96 */ +#include "net.h" + +/**************************************************************** + * (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * + ****************************************************************/ + +int key_pressed(void) +{ + REGS regsin, regsout; + regsin.h.ah = 0x01; /* read key-press */ + int86(0x16, ®sin, ®sout); + return((regsout.x.flags & 0x40) ? 0 : 1); /* zeroflag != 0 */ +} + +void clear_kb(void) +{ + REGS regsin, regsout; + while (key_pressed()) { /* zeroflag != 0 */ + regsin.h.ah = 0x00; /* read key-press */ + int86(0x16, ®sin, ®sout); + } +} + +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); +} + +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 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); +} + +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); +} +