mars_dosutils-0.01

This commit is contained in:
Mario Fetka 2011-11-13 00:40:40 +01:00
commit 5e6805dd31
22 changed files with 2673 additions and 0 deletions

46
doc Executable file
View File

@ -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.

BIN
e.pck Executable file

Binary file not shown.

201
kern.asm Executable file
View File

@ -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

12
kern.h Executable file
View File

@ -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);

317
kern.lst Executable file
View File

@ -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

4
login.bat Executable file
View File

@ -0,0 +1,4 @@
c:\net logout
c:\net login %1 %2 %3
map h:=HOME:

215
login.c Executable file
View File

@ -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);
}

40
makefile Executable file
View File

@ -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)

252
map.c Executable file
View File

@ -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);
}

4
mk.bat Executable file
View File

@ -0,0 +1,4 @@
maker %1 %2 %3 %4 > err
type err
copy net.exe c:\
del net.exe

285
ncpcall.c Executable file
View File

@ -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);
}

74
net.c Executable file
View File

@ -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);
}

BIN
net.exe Executable file

Binary file not shown.

202
net.h Executable file
View File

@ -0,0 +1,202 @@
/* net.h: 01-Feb-96 */
/****************************************************************
* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *
****************************************************************/
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <conio.h>
#include <io.h>
#include <bios.h>
#include <dos.h>
#include <process.h>
#include <stdarg.h>
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[]);

408
netcall.c Executable file
View File

@ -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(&regs, &regs, &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(&regsin, &regsout) & 0xff);
}
int logout(void)
{
REGS regsin, regsout;
regsin.x.ax = 0xd700;
return(intdos(&regsin, &regsout) & 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(&regs, &regs, &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(&regs, &regs, &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);
}

213
nwcrypt.c Executable file
View File

@ -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 <lendecke@namu01.gwdg.de> in
$* October 1995.
$*
$* Stolen to be useable for mars_nwe by
$* Martin Stover <mstover@freeway.de> 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 <jon@ddj.com> about
the legal status of this piece of code:
---
Date: Thu, 12 Oct 1995 13:44:18 +0100
From: Volker Lendecke <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 <jon@ddj.com>
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];
}

7
nwcrypt.h Executable file
View File

@ -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);

36
nwdebug.c Executable file
View File

@ -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);
}

46
nwtests.c Executable file
View File

@ -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);
}

15
slist.c Executable file
View File

@ -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[])
{
}

95
teste.c Executable file
View File

@ -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 <20>ber stat =%ld\n", stbuff.st_size);
fd = open(fn, O_RDWR | O_BINARY |O_DENYNONE);
offset = lseek(fd, 0L, SEEK_END);
printf("Filesize <20>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);
}

201
tools.c Executable file
View File

@ -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, &regsin, &regsout);
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, &regsin, &regsout);
}
}
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);
}