-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSUPPORT.C
449 lines (357 loc) · 10 KB
/
SUPPORT.C
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
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
#include <puppy.h>
#include <ascii.h>
#include <pupmem.h>
/*
Various low level and extremely important support routines. These
do not need to be customized generally to fit the target machine.
append(fname) Open or create file fname for appending.
logoff(code,disc)
Terminate this call; disconnect from the modem if
disc is true; sets code as the DOS ERRORLEVEL for this
connect. This writes out the caller record as necessary,
etc.
makefname(buf,name)
Creates a full pathname from the current (Msg, File,
Upload, pup.bbs) area. NOTE: If 'ovpath' is not blank,
it is used instead of the one from the area.
rline(f,line,len)
Read a line of text; a line is defined as characters
delimited by a CR. See the code for special cases. Returns
0 if end of file.
int num_args(string) Returns the number of args in the string, seperated
by delims (see delim(), below). Leading delimiters
are ignored.
char *next_arg(string) Returns a pointer to the next arg, delimited
by a delim, skipping over the current arg. Use via
ptr= nextarg(ptr) to skip to each argument. All
switches at the end of the current arg are skipped.
char *skip_delim(string) Skips leading delims in a string. returns a pointer.
cpyarg(to,from) Copies a string, up to the next delim or switch.
Leading and trailing delimiters are stripped (from
the output string) and a null terminator is added.
after cpyarg() FROM: foo/b foobar fipple
TO: foo
char *strip_path(out,in) Copies the disk specifier or pathname to the output
array, and returns a pointer to the name in the input
string. Drive specs are considered a path, and are
treated as such by DOS. Stripping "a:foo" and
"bin/foo/framis.asm" result in:
IN: "A:"
IN: "bin\foo"
OUT: "A:"
OUT: "bin\"
stolower(s) Convert a string to all lower case
stoupper(s) Convert a string to all upper case
atoi(s) Convert a string of digits into a numeric value; stops
when the first non-digit character is found.
str_time(s,t) Generates a static string expression of date or time, and
str_date(s,t) returns a pointer to it. Through a kludge it can be
called up to 4 times without overwriting a previous
invokation.
same_node(n1,n2) Returns true if the two nodes are the same.
cpy_node(&dest,&src)
Copies one node into another.
delim(c) Returns true if the character is a delimiter.
char *str_node(&node)
Generates a static string expression of the node, and
returns a pointer to it. Through a kludge it can be
called up to 4 times without overwriting a previous
invokation.
set_nn(string,&node)
Parse the string into various zone:net/node numbers.
This accepts "zone:net/node" format. If zone or net
isnt specified, it is left untouched.
*/
/* Display the date. */
str_date(t)
WORD t;
{
static char work[2][sizeof("31 Dec 143 ")]; /* where we keep them */
static int k; /* which one as are on */
k = ++k % 2; /* select next ... */
*work[k]= NUL; /* empty it */
sprintf(work[k],"%u %s %02u", /* the format, */
t & 0x1f, /* the day, */
months[(t >> 5) & 0x0f], /* the month name */
((t >> 9) & 0x3f) + 80); /* the year */
return(work[k]);
}
/* Display the time. */
str_time(t)
WORD t;
{
static char work[2][sizeof("23:59PM ")]; /* where we keep them */
static int k; /* which one as are on */
char hour;
k = ++k % 2; /* select next ... */
*work[k]= NUL; /* empty it */
hour= t >> 11; if (!hour) hour= 12;
sprintf(work[k],"%d:%02d",hour,(t >> 5) & 0x3f);
if (hour >= 12) strcat(work[k],"PM"); else strcat(work[k],"AM");
return(work[k]);
}
/* Open a file for appending, creating it if necessary. Return the
open handle, or -1 if error. */
append(s)
char *s;
{
int h;
char c;
h= open(s,2); /* open or create the */
if (h == -1) h= creat(s,2); /* file, if opened OK */
else lseek(h,0L,2); /* seek to the end */
return(h); /* handle or error */
}
/* Log a caller off the system; disconnect and force a termination. */
logoff(code,disc)
int code,disc;
{
int f;
char buff[SS];
long p;
limit= 0; /* disable time limits */
doscode= code; /* set result code, */
if (!test && disc) discon(); /* do disconnect, */
frc_abort(); /* force rturn to main */
}
/* Copy the path prefix, append one filename from the input string. */
makefname(d,s)
char *d,*s;
{
strcpy(d,pup.filepref); /* the path prefix, */
d= next_arg(d); /* point to its end, */
cpyarg(d,s); /* add one filename */
}
/* Display a text file. */
dspfile(filename)
char *filename;
{
int f;
f= open(filename,0);
if (f == -1) return(0);
dumptext(f);
close(f);
return(1);
}
/* Output the contents of a text file to the console. The handle of
an open file is passed. Output ceases when EOF or a Control-Z is found. */
dumptext(file)
int file;
{
char lastc,c,buff[512]; /* local buffering */
unsigned index,count;
if (file == -1) return; /* be serious */
index= count= 0; /* buffer is empty */
while (1) {
if (index >= count) { /* read some if */
index= 0; /* the local buffer */
count= read(file,buff,sizeof(buff)); /* is empty */
}
if (! count) break; /* stop if empty file */
if (abort) break; /* stop if aborted */
c= buff[index++]; /* get a character, */
if (c == LF) continue; /* ignore LFs */
if (c == CR + 128) { /* special case soft CRs */
if (lastc == ' ') continue;
c= ' ';
}
lastc= c; /* remember it, */
if (c == CR) mputs("\r\n"); /* CR becomes CR/LF */
else fmconout(c); /* else output text */
if (c == SUB) break; /* ^Z is end of file */
}
mputs("\r\n");
}
/* Write the system file out to disk. */
putsys() {
int f;
f= open("puppy.sys",2);
if (f == -1) {
printf("Can't open PUPPY.SYS!\r\n");
return;
}
write(f,&pup,sizeof(struct _pup));
close(f);
}
/* Read a line of text from the file, null terminate it. Function returns
zero if EOF. Deletes all CRs and Control-Zs from the stream. Lines are
terminated by LFs. */
rline(file,buf,len)
int file;
char *buf;
int len;
{
int i;
char notempty,c;
i= 0; notempty= 0;
--len; /* compensate for added NUL */
while (i < len) {
if (! read(file,&c,1)) break; /* stop if empty */
if (c == 0x1a) continue; /* totally ignore ^Z, */
notempty= 1; /* not empty */
if (c == '\r') continue; /* skip CR, */
if (c == '\r' + 128) continue; /* skip soft CR, */
if (c == '\n') break; /* stop if LF */
buf[i++]= c;
}
buf[i]= '\0';
return(notempty);
}
/* Return the number of args left in the string. */
num_args(s)
char *s;
{
int count;
count= 0;
s= skip_delim(s); /* skip leading blanks, */
while (*s) {
++count; /* count one, */
s= next_arg(s); /* find next, */
}
return(count);
}
/* Return a pointer to the next argument in the string. */
char *next_arg(s)
char *s;
{
while ((!delim(*s)) && *s) /* skip this one, */
++s; /* up to delim, */
s= skip_delim(s); /* then skip delims, */
return(s);
}
/* Skip over the leading delimiters in a string. */
char *skip_delim(s)
char *s;
{
while (delim(*s) && *s) {
++s;
}
return(s);
}
/* Copy the string to the destination array, stopping if we find one
of our delimiters. */
cpyatm(to,from)
char *to;
char *from;
{
while ( (!delim(*from)) && *from)
*to++= *from++;
*to= '\0';
}
/* Copy the string to the destination array, stopping if we find one
of our delimiters. */
cpyarg(to,from)
char *to;
char *from;
{
while (*from) {
if (delim(*from)) break;
*to++= *from++;
}
*to= '\0';
}
/* Strip the pathname or disk specifier from a filename, return it in a
seperate array. We do this by initially copying the entire name in, then
searching for the colon or slash. Right after the last one we find,
stuff a null, removing the name part.
Also return a pointer to the name part in the input name. */
char *strip_path(out,in)
char *out;
char *in;
{
char *name;
char *endpath;
strcpy(out,in); /* duplicate, for working, */
name= in; /* point to name, */
endpath= out; /* and end of path part, */
while (*in) { /* look for slashes or colons, */
if (*in == ':') { /* if a colon, */
endpath= ++out; /* point to name, */
name= ++in;
} else if ((*in == '/') || (*in == '\\')) {
endpath= ++out; /* move the pointer up, */
name= ++in;
} else {
++in;
++out;
}
}
*endpath= '\0'; /* delete the name part, */
return(name); /* return ptr to name part. */
}
/* Convert a string to lower case. */
stolower(s)
char *s;
{
while (*s) {
*s= tolower(*s);
++s;
}
}
/* Convert a string to upper case. */
stoupper(s)
char *s;
{
while (*s) {
*s= toupper(*s);
++s;
}
}
/* atoi() function missing from Lattice C. From Kernighan and Richie. */
atoi(s)
char *s;
{
int n;
n= 0;
while ((*s >= '0') && (*s <= '9')) {
n *= 10;
n += *s - '0';
++s;
}
return(n);
}
/* Return true if the two nodes are the same. */
same_node(n1,n2)
struct _node *n1,*n2;
{
return(
(n1-> number == n2-> number) &&
(n1-> net == n2-> net) &&
(n1-> zone == n2-> zone)
);
}
/* Copy one node structure into another. */
cpy_node(d,s)
struct _node *d,*s;
{
d-> zone= s-> zone;
d-> net= s-> net;
d-> number= s-> number;
}
/* Return a pointer to a string of the zone:net/node. */
char *str_node(n)
struct _node *n;
{
#define KLUDGE 4 /* strings we can make at once */
static char work[KLUDGE][40]; /* where we keep them */
static int k; /* which one as are on */
k = ++k % KLUDGE; /* select next ... */
*work[k]= NUL; /* empty it */
sprintf(work[k],"%d:",n-> zone);
sprintf(&work[k][strlen(work[k])],"%d/%d",n-> net,n-> number);
return(work[k]);
}
/* Return true if the character is a delimiter. */
delim(c)
char c;
{
int i;
switch (c) {
case ';':
case ' ':
case ',':
case ':':
return(1);
default: return(0);
}
}