1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
|
/* 0 */
#include "comsub.h"
#include "dpb.h"
#include <dos.h>
#include "jointype.h"
extern unsigned char *com_substr() ; /* ;AN000; DBCS enabled */
extern char getdrv() ;
union REGS inregs, outregs; /* ;AN000; Regs for Int21 */
struct SREGS segregs; /* ;AN000; Segment regs for Int21 */
#define GET_DBCS_VEC 0x6300 /* ;AN000; Int21 Get DBCS Vector */
#define DBLNULL "00" /* ;AN000; */
#define NULL 0 /* ;AN000; */
#define KANJI TRUE
/* return FALSE if drive is valid AND the path is not a prefix of a non-root
* current directory.
*/
char fPathErr(p)
char *p ;
{
char buf[MAXARG] ;
int d ;
#ifdef KANJI
char *p1;
#endif
if (p[1] == ':')
d = *p-'A'+1 ;
else
d = 0 ;
if (curdir(buf, d) == -1) /* drive is invalid => error */
return(TRUE) ;
if (strlen(buf) == 3) /* current directory is root => OK */
return(FALSE) ;
if (strpre(p, buf)) {
#ifdef KANJI
p1 = p;
while (*p1 != NULL) {
if(testkanj(*p1 & 0xFF))
p1 += 2 ;
else
if((*p1++ == '\\') && (*p1 == NULL))
return(TRUE) ;
}
#else
if (p[strlen(p)-1] == '\\') /* prefix matched, prefix had...*/
return(TRUE) ; /* ...trailing / => valid ... */
/* ...prefix => ERROR */
#endif
d = buf[strlen(p)] ;
if (d == 0 || d == '\\') /* prefix matched,... */
return(TRUE) ; /* ...prefix had no trailing /, */
/* ...next char was / => ... */
/* ...valid prefix => ERROR */
} ;
return(FALSE) ; /* drive letter good and not valid prefix => OK */
}
strpre(pre, tot)
char *pre;
char *tot;
{
return(!strncmp(pre, tot, strlen(pre)));
}
Fatal(p)
char *p ;
{
printf("%s\n", p) ;
exit(1) ;
}
ffirst(pb, attr, pfbuf)
char *pb ;
int attr ;
struct findType *pfbuf ;
{
union REGS regs ;
/* set DMA to point to buffer */
regs.h.ah = 0x1A ;
regs.x.dx = (unsigned) pfbuf ;
intdos (®s, ®s) ;
/* perform system call */
regs.h.ah = 0x4E ;
regs.x.cx = attr ;
regs.x.dx = (unsigned) pb ;
intdos (®s, ®s) ;
return (regs.x.cflag ? -1 : 0) ;
}
fnext (pfbuf)
struct findType *pfbuf;
{
union REGS regs;
/* set DMA to point to buffer */
regs.h.ah = 0x1A;
regs.x.dx = (unsigned) pfbuf;
intdos (®s, ®s);
/* perform system call */
regs.h.ah = 0x4F;
intdos (®s, ®s);
return (regs.x.cflag ? -1 : 0) ;
}
char *strbscan(str, class)
char *str ;
char *class ;
{
char *p ;
p = com_substr(str, class) ; /* :AN000; DBCS function */
return((p == NULL) ? (str + strlen(str)) : p) ;
}
/* curdir.c - return text of current directory for a particular drive */
curdir (dst, drive)
char *dst ;
int drive ;
{
union REGS regs ;
*dst++ = PathChr ;
regs.h.ah = 0x47 ;
regs.h.dl = drive ;
regs.x.si = (unsigned) dst ;
intdos (®s, ®s) ;
return(regs.x.cflag ? -1 : 0) ;
}
/*
rootpath
*/
/*** rootpath -- convert a pathname argument to root based cannonical form
*
* rootpath determines the current directory, appends the path argument (which
* may affect which disk the current directory is relative to), and qualifies
* "." and ".." references. The result is a complete, simple, path name with
* drive specifier.
*
* If the relative path the user specifies does not include a drive spec., the
* default drive will be used as the base. (The default drive will never be
* changed.)
*
* entry: relpath -- pointer to the pathname to be expanded
* fullpath -- must point to a working buffer, see warning
* exit: fullpath -- the full path which results
* return: true if an error occurs, false otherwise
*
* calls: curdir, getdrv
*
* warning: fullpath must point to a working buffer large enough to hold the
* longest possible relative path argument plus the longest possible
* current directory path.
*
*/
int rootpath(relpath, fullpath)
char *relpath ;
char *fullpath ;
{
int drivenum ;
char tempchar;
register char *lead, *follow ;
char *p1, *p2;
/* extract drive spec */
drivenum = getdrv() ;
if ((*relpath != NULL) && (relpath[1] == COLON)) {
drivenum = relpath[0] - 'A' ;
relpath += 2 ;
}
fullpath[0] = (char) ('A' + drivenum) ;
fullpath[1] = COLON ;
/* append relpath to fullpath/base */
if (*relpath == PathChr) {
/* relpath starts at base */
strcpy(fullpath+2, relpath) ;
}
else {
/* must get base path first */
if (curdir(fullpath+2, drivenum+1))
return(TRUE) ; /* terrible error */
if ((*relpath != ASCNULL) && (strlen(fullpath) > 3))
strcat(fullpath, "\\") ;
strcat(fullpath, relpath) ;
}
/* convert path to cannonical form */
lead = fullpath ;
while(*lead != ASCNULL) {
/* mark next path segment */
follow = lead ;
lead = (char *) com_substr(follow+1, "\\") ; /* ;AC000; */
if (lead == NULL)
lead = fullpath + strlen(fullpath) ;
tempchar = *lead ;
if (tempchar == PathChr)
tempchar = BACKSLASH ; /* make breaks uniform */
*lead = ASCNULL ;
/* "." segment? */
if (strcmp(follow+1, ".") == 0) {
*lead = tempchar ;
strcpy(follow, lead) ; /* remove "." segment */
lead = follow ;
}
/* ".." segment? */
else if (strcmp(follow+1, "..") == 0) {
*lead = tempchar ;
tempchar = *follow ;
*follow = NULL ;
p2 = fullpath - 1 ;
while(*(p2=strbscan(p1=p2+1,"\\")) != NULL) ;
/* p1 now points to the start of the previous element */
*follow = tempchar ;
if(p1 == fullpath)
return(TRUE) ; /* tried to .. the root */
follow = p1 - 1 ; /* follow points to path sep */
strcpy(follow, lead) ; /* remove ".." segment */
lead = follow ;
}
/* normal segment */
else
*lead = tempchar ;
}
if (strlen(fullpath) == 2) /* 'D:' or some such */
strcat(fullpath, "\\") ;
return(FALSE) ;
}
/* getdrv - return current drive as a character */
char getdrv()
{
union REGS regs ;
regs.h.ah = CURDISK ; /* Function 0x19 */
intdos (®s, ®s) ;
return(regs.h.al) ;
}
testkanj(c)
unsigned char c;
{
char fix_es_reg[1]; /* ;AN000; Fixes es reg after "far" */
char far * fptr; /* ;AN000; Pts to DBCS vector */
unsigned * ptr; /* ;AN000; Input to fptr */
unsigned int got_dbcs; /* ;AN000; Flag */
inregs.x.ax = GET_DBCS_VEC; /* ;AN000; 0x6300 */
intdosx(&inregs,&outregs,&segregs); /* ;AN000; Int21 */
got_dbcs = FALSE; /* ;AN000; Initialize */
ptr = (unsigned *)&fptr; /* ;AN000; Int21 returns DS:SI */
*ptr = outregs.x.si; /* ;AN000; as ptr to DBCS */
ptr++; /* ;AN000; vector, now fill */
*ptr = segregs.ds; /* ;AN000; in our pointer */
for (fptr; *(unsigned far *)fptr != (unsigned)DBLNULL; fptr += 2) /* ;AN000; */
{ /* ;AN000; */
if ( (c >= (char)*fptr) && (c <= (char)*(fptr+1)) ) /* ;AN000; Is char */
{ /* ;AN000; within the range? */
got_dbcs = TRUE; /* ;AN000; Char is DBCS */
break; /* ;AN000; */
} /* ;AN000; */
} /* ;AN000; */
strcpy(fix_es_reg,NULL); /* ;AN000; Repair ES reg */
return(got_dbcs); /* ;AN000; */
}
|