summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/FILESYS/FILESYS.C
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/FILESYS/FILESYS.C')
-rw-r--r--v4.0/src/CMD/FILESYS/FILESYS.C922
1 files changed, 922 insertions, 0 deletions
diff --git a/v4.0/src/CMD/FILESYS/FILESYS.C b/v4.0/src/CMD/FILESYS/FILESYS.C
new file mode 100644
index 0000000..9ae7f41
--- /dev/null
+++ b/v4.0/src/CMD/FILESYS/FILESYS.C
@@ -0,0 +1,922 @@
1/*  */
2/*----------------------------------------------------------------------+
3| |
4| FILESYS provides an interface to IFSFUNC to allow assignment of |
5| logical drive letters to various devices. |
6| |
7| FILESYS also allows the user to cancel the attach for a drive |
8| or device or list the currently attched devices. |
9| |
10| |
11| ALIAS provides an interface to IFSFUNC that allows the user |
12| to cause automatic substitution of an alternate filename string |
13| for a pseudo-device driver name. |
14| |
15| PROGRAM PROPERTY OF Microsoft, Copyright 1988 Microsoft Corp. |
16| |
17| INPUT: |
18| Command line from user. |
19| |
20| OUTPUT: |
21| Attached device, detached device, or list of attached devices. |
22| |
23+----------------------------------------------------------------------*/
24
25#include "stdio.h" /* ;an000; */
26#include "stdlib.h" /* ;an000; */
27#include "dos.h" /* allows use of intdos calls */ /* ;an000; */
28#include "string.h" /* allows use of str* calls */ /* ;an000; */
29#include "parse.h" /* allows use of parser */ /* ;an000; */
30#include "msgret.h" /* allows use of msg ret */ /* ;an000; */
31 /* ;an000; */
32#define ZERO 0 /* ;an002; */
33#define NULL 0 /* ;an000; */
34#define FALSE 0 /* ;an000; */
35#define TRUE 1 /* ;an000; */
36 /* ;an000; */
37#define MORE_DEVICES 0x0000 /* more devices in list */ /* ;an000; */
38#define NO_MORE_FILES 0x0012 /* no more files DOS error */ /* ;an000; */
39#define INVALID_FUNCTION_NUM 0x0001 /* invalid function - Get RDR list */ /* ;an000; */
40 /* ;an000; */
41#define IFS_DEVICE 0X01 /* IFS device type */ /* ;an000; */
42#define IFS_DRIVE 0X02 /* IFS drive type */ /* ;an000; */
43#define NET_PRINTER 0x03 /* network printer device type */ /* ;an000; */
44#define NET_DRIVE 0x04 /* network drive device type */ /* ;an000; */
45 /* ;an000; */
46#define GET_PAUSE_STATUS 0x5f00 /* DOS call to get pause status */ /* ;an000; */
47#define GET_REDIR_LIST_ENTRY 0x5f02 /* DOS call to get redir entry */ /* ;an000; */
48#define REDIRECT_DEVICE 0x5f03 /* DOS call to redir device */ /* ;an000; */
49#define CANCEL_REDIRECTION 0x5f04 /* DOS call to cancel redirection */ /* ;an000; */
50#define GET_ATTACH_LIST 0x5f06 /* DOS call to get attached devices*/ /* ;an000; */
51#define GET_EXTENDED_ERROR 0x5900 /* DOS call to get extended error */ /* ;an000; */
52 /* ;an000; */
53#define CARRY_FLAG 0x0001 /* mask for carry flag */ /* ;an000; */
54#define PARITY_FLAG 0x0004 /* mask for parity flag */ /* ;an000; */
55#define ACARRY_FLAG 0x0010 /* mask for aux carry flag */ /* ;an000; */
56#define ZERO_FLAG 0x0040 /* mask for zero flag */ /* ;an000; */
57#define SIGN_FLAG 0x0080 /* mask for sign flag */ /* ;an000; */
58#define TRAP_FLAG 0x0100 /* mask for trap flag */ /* ;an000; */
59#define INTERRUPT_FLAG 0x0200 /* mask for interrupt flag */ /* ;an000; */
60#define DIRECTION_FLAG 0x0400 /* mask for direction flag */ /* ;an000; */
61#define OVERFLOW_FLAG 0x0800 /* mask for overflow flag */ /* ;an000; */
62 /* ;an000; */
63 /* ;an000; */
64/************************************************************************/ /* ;an000; */
65/* */ /* ;an000; */
66/* Define subroutines */ /* ;an000; */
67/* */ /* ;an000; */
68/************************************************************************/ /* ;an000; */
69void main(int, char *[]); /* ;an000; */
70void parse_init(void); /* ;an000; */
71void device_attach(int, char *, char *, char *); /* ;an000; */
72void device_detach(char *); /* ;an000; */
73void fs_status(char *); /* ;an000; */
74int get_pause_stat(unsigned char); /* ;an000; */
75void fs_error(int); /* ;an000; */
76void fs_build_print_message(int, char *, char *, char *); /* ;an000; */
77void string_build(void); /* ;an000; */
78void check_pause_status(unsigned char, int *, int *, int *); /* ;an000; */
79void print_status(int, int, int, int *); /* ;an000; */
80void Sub0_Message(int,int,unsigned char); /* ;an000; */
81void fs_strcpy(char *, char far *); /* ;an000; */
82int fs_strlen(char far *); /* ;an000; */
83 /* ;an000; */
84extern void sysloadmsg(union REGS *, union REGS *); /* ;an000; */
85extern void sysdispmsg(union REGS *, union REGS *); /* ;an000; */
86extern void parse(union REGS *, union REGS *); /* ;an000; */
87 /* ;an000; */
88 /* ;an000; */
89struct p_parms p_p; /* ;an000; */
90struct p_parms p_p1; /* ;an000; */
91 /* ;an000; */
92struct p_parmsx p_px; /* ;an000; */
93struct p_parmsx p_px1; /* ;an000; */
94 /* ;an000; */
95struct p_control_blk p_con1; /* ;an000; */
96struct p_control_blk p_con1a; /* ;an000; */
97struct p_control_blk p_con2; /* ;an000; */
98struct p_control_blk p_con3; /* ;an000; */
99struct p_control_blk p_con4; /* ;an000; */
100 /* ;an000; */
101struct p_control_blk p_swt1; /* ;an000; */
102 /* ;an000; */
103struct p_result_blk p_result1; /* ;an000; */
104struct p_result_blk_D p_resultD; /* ;an000; */
105 /* ;an000; */
106 /* ;an000; */
107struct p_value_blk p_noval; /* ;an000; */
108 /* ;an000; */
109 /* ;an000; */
110char cmd_line[128]; /* ;an000; */
111char far *cmdline; /* ;an000; */
112 /* ;an000; */
113 /* ;an000; */
114 struct sublistx /* sublist for replaceable parms. */ /* ;an000; */
115 { /* ;an000; */
116 unsigned char size; /* sublist size */ /* ;an000; */
117 unsigned char reserved; /* reserved for future growth */ /* ;an000; */
118 unsigned far *value; /* pointer to replaceable parm */ /* ;an000; */
119 unsigned char id; /* type of replaceable parm */ /* ;an000; */
120 unsigned char flags; /* how parm is to be displayed */ /* ;an000; */
121 unsigned char max_width; /* max width of replaceable field */ /* ;an000; */
122 unsigned char min_width; /* min width of replaceable field */ /* ;an000; */
123 unsigned char pad_char; /* pad character for replaceable field */ /* ;an000; */
124 } sublist[4]; /* end of sublis */ /* ;an000; */
125 /* ;an000; */
126 /* ;an000; */
127 /* ;an000; */
128struct /* ;an000; */
129 { /* ;an000; */
130 char *target_fs_name; /* ;an000; */
131 unsigned int target_count; /* ;an000; */
132 char target_string[128]; /* ;an000; */
133 } GAL_Target; /* ;an000; */
134 /* ;an000; */
135struct /* ;an000; */
136 { /* ;an000; */
137 char device_string[9]; /* ;an000; */
138 } GAL_Device; /* ;an000; */
139 /* ;an000; */
140 /* ;an000; */
141struct /* ;an000; */
142 { /* ;an000; */
143 char *attach_system; /* pointer to filesys arg */ /* ;an000; */
144 unsigned int attach_parms_num; /* number of additional parms */ /* ;an000; */
145 char attach_addl_parms[128];/* additional parms */ /* ;an000; */
146 /* ;an000; */
147 } Attach_block; /* ;an000; */
148 /* ;an000; */
149/*----------------------------------------------------------------------+
150| define register variables |
151+----------------------------------------------------------------------*/
152union REGS inregs, outregs; /* ;an000; */
153struct SREGS segregs; /* ;an000; */
154 /* ;an000; */
155 /* ;an000; */
156/*----------------------------------------------------------------------+
157| |
158| main - filesys and alias main routine |
159| |
160| handle parsing command line and calling all other routines |
161| |
162+----------------------------------------------------------------------*/
163 /* ;an000; */
164void main(argc,argv) /* ;an000; */
165 /* ;an000; */
166int argc; /* number of arguments passed on command line */ /* ;an000; */
167char *argv[]; /* array of pointer to arguments */ /* ;an000; */
168 /* ;an000; */
169 { /* ;an000; */
170/*----------------------------------------------------------------------+
171| define some local variables |
172+----------------------------------------------------------------------*/
173 int arg_index; /* index used for stepping through args */ /* ;an000; */
174 int more_arguments; /* flag used while looping calls to parser */ /* ;an000; */
175 int i; /* loop counter */ /* ;an000; */
176 int detach_flag; /* signal to detach device */ /* ;an000; */
177 int good_parse; /* signal a good parse occurred */ /* ;an000; */
178 /* ;an000; */
179 char *string_ptr; /* pointer to a string */ /* ;an000; */
180 char file_spec_buf[64]; /* buffer to hold drive or device name */ /* ;an000; */
181 char fs_name_buf[64]; /* buffer to hold file system name */ /* ;an000; */
182 char string_buf[128]; /* buffer to hold device parms */ /* ;an000; */
183 char drive_letter; /* drive letter to attach/detach */ /* ;an000; */
184 /* ;an000; */
185/*----------------------------------------------------------------------+
186| get started by calling the parser |
187+----------------------------------------------------------------------*/
188 /* ;an000; */
189 sysloadmsg(&inregs, &outregs); /* load the messages */ /* ;an000; */
190 if ((outregs.x.cflag & CARRY_FLAG) == CARRY_FLAG) /* error? */ /* ;an000; */
191 sysdispmsg(&outregs,&outregs); /* tell user error and exit */ /* ;an000; */
192 else /* execute program */ /* ;an000; */
193 { /* ;an000; */
194 inregs.h.ah = (unsigned char) 0x62; /* ;an000; */
195 intdosx(&inregs, &inregs, &segregs); /* ;an000; */
196 /* ;an000; */
197 FP_OFF(cmdline) = 0x81; /* ;an000; */
198 FP_SEG(cmdline) = inregs.x.bx; /* ;an000; */
199 /* ;an000; */
200 i = 0; /* ;an000; */
201 while ( *cmdline != (char) '\x0d' ) cmd_line[i++] = *cmdline++; /* ;an000; */
202 cmd_line[i++] = (char) '\x0d'; /* ;an000; */
203 cmd_line[i++] = (char) '\0'; /* ;an000; */
204 /* ;an000; */
205 /* ;an000; */
206 file_spec_buf[0] = NULL; /* ;an000; */
207 string_ptr = Attach_block.attach_addl_parms; /* ;an000; */
208 detach_flag = FALSE; /* ;an000; */
209 good_parse = TRUE; /* ;an000; */
210 /* ;an000; */
211 parse_init(); /* ;an000; */
212 inregs.x.si = (unsigned)cmd_line; /* ;an000; */
213 inregs.x.cx = (unsigned)0; /* ;an000; */
214 inregs.x.dx = (unsigned)0; /* ;an000; */
215 inregs.x.di = (unsigned)&p_p; /* point to drive spec block */ /* ;an000; */
216 /* ;an000; */
217 i = 0; /* ;an000; */
218 parse(&inregs,&outregs); /* ;an000; */
219 if (outregs.x.ax != p_no_error) /* ;an000; */
220 { /* ;an000; */
221 inregs.x.si = (unsigned)cmd_line; /* ;an000; */
222 inregs.x.cx = (unsigned)0; /* ;an000; */
223 inregs.x.dx = (unsigned)0; /* ;an000; */
224 inregs.x.di = (unsigned)&p_p1; /* point to simple string block */ /* ;an000; */
225 parse(&inregs,&outregs); /* ;an000; */
226 } /* ;an000; */
227 while ((outregs.x.ax == p_no_error) && (good_parse == TRUE)) /* ;an000; */
228 { /* ;an000; */
229 i++; /* ;an000; */
230 if (p_resultD.D_Type == p_drive) /* ;an000; */
231 { /* ;an000; */
232 drive_letter = (char) p_resultD.D_Res_Drive + ('A'-1); /* ;an000; */
233 file_spec_buf[0] = drive_letter; /* ;an000; */
234 file_spec_buf[1] = (char) ':'; /* ;an000; */
235 file_spec_buf[2] = (char) '\0'; /* ;an000; */
236 } /* ;an000; */
237 /* ;an000; */
238 if ((p_result1.P_Type == p_string) && ( i == 1)) /* ;an000; */
239 fs_strcpy(file_spec_buf,p_result1.p_result_buff); /* ;an000; */
240 /* ;an000; */
241 if ((p_result1.P_Type == p_string) && (i == 2)) /* ;an000; */
242 fs_strcpy(fs_name_buf,p_result1.p_result_buff); /* ;an000; */
243 /* ;an000; */
244 if ((p_result1.P_Type == p_string) && (i > 2)) /* ;an000; */
245 { /* ;an000; */
246 fs_strcpy(string_ptr,p_result1.p_result_buff); /* ;an000; */
247 string_ptr += fs_strlen(p_result1.p_result_buff); /* ;an000; */
248 string_ptr++; /* ;an000; */
249 } /* ;an000; */
250 if (p_result1.P_SYNONYM_Ptr == (unsigned int)p_swt1.p_keyorsw) /* ;an000; */
251 { /* ;an000; */
252 if (i != 2) /* switch in wrong place */ /* ;an000; */
253 { /* ;an000; */
254 outregs.x.ax = p_syntax; /* signal error type */ /* ;an000; */
255 good_parse = FALSE; /* ;an000; */
256 } /* ;an000; */
257 detach_flag = TRUE; /* ;an000; */
258 } /* ;an000; */
259 if (good_parse == TRUE) /* ;an000; */
260 parse(&outregs,&outregs); /* ;an000; */
261 } /* ;an000; */
262 /* ;an000; */
263 if (outregs.x.ax != p_rc_eol) /* an000; dms; parse error */ /* ;an000; */
264 { /* ;an000; */
265 Sub0_Message(outregs.x.ax,STDOUT,Parse_Err_Class); /* an000; dms; tell user error */ /* ;an000; */
266 exit(1); /* an000; dms; exit program */ /* ;an000; */
267 } /* ;an000; */
268 /* ;an000; */
269 /* which routine to invoke? */ /* ;an000; */
270 switch (i) /* ;an000; */
271 { /* ;an000; */
272 case 0: fs_status(file_spec_buf); /* an000; dms; no parms - status */ /* ;an000; */
273 break; /* ;an000; */
274 /* ;an000; */
275 case 1: fs_status(file_spec_buf); /* an000; dms; 1 parm - selective status*/ /* ;an000; */
276 break; /* ;an000; */
277 /* ;an000; */
278 default : if ((i == 2) && (detach_flag == TRUE)) /* an000; dms; detach request? */ /* ;an000; */
279 device_detach(file_spec_buf); /* an000; dms; yes */ /* ;an000; */
280 else /* ;an000; */
281 device_attach(i,file_spec_buf,fs_name_buf,string_buf); /*an000; dms; attach request */ /* ;an000; */
282 break; /* ;an000; */
283 } /* ;an000; */
284 /* ;an000; */
285 /* ;an000; */
286 } /* end FILESYS MAIN */ /* ;an000; */
287 } /* ;an000; */
288 /* ;an000; */
289 /* ;an000; */
290/*----------------------------------------------------------------------+
291| |
292| SUBROUTINE NAME: PARSE_INIT |
293| |
294| SUBROUTINE FUNCTION: |
295| |
296| This routine is called by the FILESYS MAIN routine to initialize|
297| the parser data structures. |
298| |
299| INPUT: |
300| none |
301| |
302| OUTPUT: |
303| properly initialized parser control blocks |
304| |
305+----------------------------------------------------------------------*/
306void parse_init() /* ;an000; */
307 { /* ;an000; */
308 p_p.p_parmsx_address = &p_px; /* address of extended parm list */ /* ;an000; */
309 p_p.p_num_extra = 0; /* ;an000; */
310 /* ;an000; */
311 p_p1.p_parmsx_address = &p_px1; /* address of extended parm list */ /* ;an000; */
312 p_p1.p_num_extra = 0; /* ;an000; */
313 /* ;an000; */
314 p_px.p_minp = 0; /* ;an000; */
315 p_px.p_maxp = 4; /* ;an000; */
316 p_px.p_control[0] = &p_con1; /* ;an000; */
317 p_px.p_control[1] = &p_con2; /* ;an000; */
318 p_px.p_control[2] = &p_con3; /* ;an000; */
319 p_px.p_control[3] = &p_con4; /* ;an000; */
320 p_px.p_maxswitch = 1; /* ;an000; */
321 p_px.p_switch[0] = &p_swt1; /* ;an000; */
322 p_px.p_maxkeyword = 0; /* ;an000; */
323 /* ;an000; */
324 p_px1.p_minp = 0; /* ;an000; */
325 p_px1.p_maxp = 4; /* ;an000; */
326 p_px1.p_control[0] = &p_con1a; /* ;an000; */
327 p_px1.p_control[1] = &p_con2; /* ;an000; */
328 p_px1.p_control[2] = &p_con3; /* ;an000; */
329 p_px1.p_control[3] = &p_con4; /* ;an000; */
330 p_px1.p_maxswitch = 1; /* ;an000; */
331 p_px1.p_switch[0] = &p_swt1; /* ;an000; */
332 p_px1.p_maxkeyword = 0; /* ;an000; */
333 /* ;an000; */
334 p_con1.p_match_flag = p_drv_only+ p_ig_colon+ p_optional; /* ;an000; */
335 p_con1.p_function_flag = p_cap_char+ p_rm_colon; /* ;an000; */
336 p_con1.p_result_buf = (unsigned int)&p_resultD; /* ;an000; */
337 p_con1.p_value_list = (unsigned int)&p_noval; /* ;an000; */
338 p_con1.p_nid = 0; /* ;an000; */
339 p_con1.p_keyorsw[0] = 0; /* ;an000; */
340 /* ;an000; */
341 p_con1a.p_match_flag = p_simple_s+ p_optional; /* ;an000; */
342 p_con1a.p_function_flag = p_cap_char; /* ;an000; */
343 p_con1a.p_result_buf = (unsigned int)&p_result1; /* ;an000; */
344 p_con1a.p_value_list = (unsigned int)&p_noval; /* ;an000; */
345 p_con1a.p_nid = 0; /* ;an000; */
346 p_con1a.p_keyorsw[0] = 0; /* ;an000; */
347 /* ;an000; */
348 p_con2.p_match_flag = p_simple_s+ p_optional; /* ;an000; */
349 p_con2.p_function_flag = p_cap_char; /* ;an000; */
350 p_con2.p_result_buf = (unsigned int)&p_result1; /* ;an000; */
351 p_con2.p_value_list = (unsigned int)&p_noval; /* ;an000; */
352 p_con2.p_nid = 0; /* ;an000; */
353 p_con2.p_keyorsw[0] = 0; /* ;an000; */
354 /* ;an000; */
355 p_con3.p_match_flag = p_simple_s+ p_optional; /* ;an000; */
356 p_con3.p_function_flag = p_cap_char; /* ;an000; */
357 p_con3.p_result_buf = (unsigned int)&p_result1; /* ;an000; */
358 p_con3.p_value_list = (unsigned int)&p_noval; /* ;an000; */
359 p_con3.p_nid = 0; /* ;an000; */
360 p_con3.p_keyorsw[0] = 0; /* ;an000; */
361 /* ;an000; */
362 p_con4.p_match_flag = p_simple_s+ p_optional; /* ;an000; */
363 p_con4.p_function_flag = p_cap_char; /* ;an000; */
364 p_con4.p_result_buf = (unsigned int)&p_result1; /* ;an000; */
365 p_con4.p_value_list = (unsigned int)&p_noval; /* ;an000; */
366 p_con4.p_nid = 0; /* ;an000; */
367 p_con4.p_keyorsw[0] = 0; /* ;an000; */
368 /* ;an000; */
369 p_swt1.p_match_flag = p_none; /* ;an000; */
370 p_swt1.p_function_flag = p_cap_char; /* ;an000; */
371 p_swt1.p_result_buf = (unsigned int)&p_result1; /* ;an000; */
372 p_swt1.p_value_list = (unsigned int)&p_noval; /* ;an000; */
373 p_swt1.p_nid = 1; /* ;an000; */
374 strcpy(p_swt1.p_keyorsw,"/D"+NULL); /* ;an000; */
375 /* ;an000; */
376 p_noval.p_val_num = 0; /* ;an000; */
377 /* ;an000; */
378 p_result1.P_Type = 0; /* ;an000; */
379 p_result1.P_Item_Tag = 0; /* ;an000; */
380 p_result1.P_SYNONYM_Ptr = 0; /* ;an000; */
381 /* ;an000; */
382 /* ;an000; */
383 p_resultD.D_Type = 0; /* ;an000; */
384 p_resultD.D_Item_Tag = 0; /* ;an000; */
385 p_resultD.D_SYNONYM_Ptr = 0; /* ;an000; */
386 p_resultD.D_Res_Drive = 0; /* ;an000; */
387 /* ;an000; */
388 return; /* ;an000; */
389 /* ;an000; */
390 } /* end parse_init */ /* ;an000; */
391 /* ;an000; */
392 /* ;an000; */
393/*----------------------------------------------------------------------+
394| |
395| SUBROUTINE NAME: DEVICE_ATTACH |
396| |
397| SUBROUTINE FUNCTION: |
398| |
399| This routine is called by the FILESYS MAIN routine when it has |
400| determined that a device attach request has been included |
401| on the FILESYS command line. |
402| |
403| INPUT: |
404| device to attach and ifs name |
405| |
406| OUTPUT: |
407| None |
408| |
409+----------------------------------------------------------------------*/
410void device_attach(parm_cnt, drive_ptr, fs_name_ptr, parm_ptr) /* ;an000; */
411 /* ;an000; */
412 int parm_cnt; /* ;an000; */
413 char *drive_ptr; /* ;an000; */
414 char *fs_name_ptr; /* ;an000; */
415 char *parm_ptr; /* ;an000; */
416 /* ;an000; */
417 { /* ;an000; */
418 /* ;an000; */
419 strcpy(GAL_Device.device_string,drive_ptr); /* ;an000; */
420 Attach_block.attach_system = fs_name_ptr; /* ;an000; */
421 Attach_block.attach_parms_num = parm_cnt - 2; /* ;an000; */
422 /* ;an000; */
423 if (strchr(drive_ptr,(char)':') != 0) /* ;an000; */
424 inregs.h.bl = IFS_DRIVE; /* ;an000; */
425 else /* ;an000; */
426 inregs.h.bl = IFS_DEVICE; /* ;an000; */
427 /* ;an000; */
428 /* ;an000; */
429 inregs.x.ax = REDIRECT_DEVICE; /* fcn code for redir device */ /* ;an000; */
430 inregs.x.si = (unsigned int) &GAL_Device; /* ;an000; */
431 inregs.x.di = (unsigned int) &Attach_block; /* point to dest */ /* ;an000; */
432 inregs.x.cx = 0; /* = 0 for network compat. */ /* ;an000; */
433 /* ;an000; */
434 intdos(&inregs, &outregs); /* make the call */ /* ;an000; */
435 /* ;an000; */
436 if ((outregs.x.cflag & CARRY_FLAG) == CARRY_FLAG) fs_error(outregs.x.ax); /* ;an000; */
437 return; /* ;an000; */
438 } /* end of device attach */ /* ;an000; */
439 /* ;an000; */
440 /* ;an000; */
441/*----------------------------------------------------------------------+
442| |
443| SUBROUTINE NAME: DEVICE_DETACH |
444| |
445| SUBROUTINE FUNCTION: |
446| |
447| This routine is called by the FILESYS MAIN routine when it has |
448| determined that a device detach request has been included |
449| on the FILESYS command line. |
450| |
451| INPUT: |
452| device to detach |
453| |
454| OUTPUT: |
455| None |
456| |
457+----------------------------------------------------------------------*/
458void device_detach(char *rd_source) /* source for detach (e.g. LPT1:, E:) */ /* ;an000; */
459 { /* ;an000; */
460 inregs.x.ax = CANCEL_REDIRECTION; /* fcn code for cancel redir */ /* ;an000; */
461 inregs.x.si = (unsigned int) rd_source; /* point to source */ /* ;an000; */
462 /* ;an000; */
463 intdos(&inregs, &outregs); /* make the call */ /* ;an000; */
464 /* ;an000; */
465 /* ;an000; */
466 if ((outregs.x.cflag & CARRY_FLAG) == CARRY_FLAG) fs_error(outregs.x.ax); /* ;an000; */
467 } /* end of device detach */ /* ;an000; */
468 /* ;an000; */
469 /* ;an000; */
470/*----------------------------------------------------------------------+
471| |
472| fs_status - display attach or alias list |
473| |
474| Inputs : name - pointer to a specific device |
475| |
476| Outputs : status report of current attached state |
477| |
478+----------------------------------------------------------------------*/
479void fs_status(char *name) /* ;an000; */
480 { /* ;an000; */
481 int redir_index; /* counter variable */ /* ;an000; */
482 int first_net_entry; /* flag */ /* ;an000; */
483 int np_paused; /* flag */ /* ;an000; */
484 int nd_paused; /* flag */ /* ;an000; */
485 int entry_type; /* save the device entry type */ /* ;an000; */
486 int error_type; /* save the device error type */ /* ;an002; */
487 int message_type; /* value of message to build*/ /* ;an000; */
488 int search_flag; /* flag */ /* ;an000; */
489 int header_flag; /* flag used to help decide if header should be displayed */ /* ;an000; */
490 char fs_name_array[9]; /* ;an000; */
491 /* ;an000; */
492 /* initialize some things */ /* ;an000; */
493 /* ;an000; */
494 GAL_Target.target_fs_name = (char *)fs_name_array; /* ;an000; */
495 redir_index = 0; /* always start with entry 0 */ /* ;an000; */
496 first_net_entry = TRUE; /* so we don't check for pause on */ /* ;an000; */
497 /* every net entry */ /* ;an000; */
498 np_paused = FALSE; /* always assume NOT paused */ /* ;an000; */
499 nd_paused = FALSE; /* ;an000; */
500 header_flag = FALSE; /* always initialze as false */ /* ;an000; */
501 /* ;an000; */
502 if (name[0] == NULL) /* an000; dms;specific device search? */ /* ;an000; */
503 /* ;an000; */
504 search_flag = FALSE; /* an000; dms;no */ /* ;an000; */
505 /* ;an000; */
506 else /* ;an000; */
507 search_flag = TRUE; /* an000; dms;yes */ /* ;an000; */
508 /* ;an000; */
509 /* search through redir list */ /* ;an000; */
510 /* ;an000; */
511 inregs.x.ax = GET_ATTACH_LIST; /* an000; dms;get list of devices */ /* ;an000; */
512 inregs.x.bx = redir_index; /* an000; dms;list entry number */ /* ;an000; */
513 inregs.x.si = (unsigned int)&GAL_Device; /* an000; dms;point to device buffer */ /* ;an000; */
514 inregs.x.di = (unsigned int)&GAL_Target; /* an000; dms;point to target buffer */ /* ;an000; */
515 intdos(&inregs,&outregs); /* an000; dms;invoke call */ /* ;an000; */
516 while ((outregs.x.ax != NO_MORE_FILES) && /* ;an000; */
517 ((outregs.x.cflag & CARRY_FLAG) != CARRY_FLAG)) /* ;an000; */
518 { /* ;an000; */
519 error_type = outregs.h.bh; /* an000; drm;save error type */ /* ;an002; */
520 entry_type = outregs.h.bl; /* an000; dms;save device type */ /* ;an000; */
521 if (search_flag == TRUE) /* an000; dms;specific device? */ /* ;an000; */
522 { /* ;an000; */
523 if (strcmpi(GAL_Device.device_string,name) == 0) /* an000; dms;found the device? */ /* ;an000; */
524 { /* ;an000; */
525 Sub0_Message(TITLE1,STDOUT,Utility_Msg_Class); /* an000; dms; print header for status */ /* ;an000; */
526 Sub0_Message(TITLE2,STDOUT,Utility_Msg_Class); /* ;an000; */
527 Sub0_Message(TITLE3,STDOUT,Utility_Msg_Class); /* ;an000; */
528 header_flag = TRUE; /* ;an000; */
529 /* ;an000; */
530 check_pause_status(entry_type, /* ;an001; */
531 &np_paused, /* ;an000; */
532 &nd_paused, /* ;an000; */
533 &first_net_entry); /* ;an000; */
534 string_build(); /* an000; dms;build string */ /* ;an000; */
535 if (error_type != ZERO)
536 message_type = ERROR_RDR_MSG; /* ;an002; */
537 else /* ;an002; */
538 print_status(entry_type, /* ;an000; */
539 np_paused, /* ;an000; */
540 nd_paused, /* ;an000; */
541 &message_type); /* ;an000; */
542 fs_build_print_message(message_type, /* ;an000; */
543 GAL_Device.device_string, /* ;an000; */
544 GAL_Target.target_fs_name, /* ;an000; */
545 GAL_Target.target_string); /* ;an000; */
546 } /* ;an000; */
547 } /* ;an000; */
548 else /* ;an000; */
549 { /* ;an000; */
550 if (!header_flag) /* logic to display headers only once */ /* ;an000; */
551 { /* ;an000; */
552 Sub0_Message(TITLE1,STDOUT,Utility_Msg_Class); /* an000; dms; print header for status */ /* ;an000; */
553 Sub0_Message(TITLE2,STDOUT,Utility_Msg_Class); /* ;an000; */
554 Sub0_Message(TITLE3,STDOUT,Utility_Msg_Class); /* ;an000; */
555 header_flag = TRUE; /* ;an000; */
556 } /* ;an000; */
557 /* ;an000; */
558 check_pause_status(entry_type, /* ;an001; */
559 &np_paused, /* ;an000; */
560 &nd_paused, /* ;an000; */
561 &first_net_entry); /* ;an000; */
562 string_build(); /* an000; dms;build string */ /* ;an000; */
563 if (error_type != ZERO)
564 message_type = ERROR_RDR_MSG; /* ;an002; */
565 else /* ;an002; */
566 print_status(entry_type, /* ;an000; */
567 np_paused, /* ;an000; */
568 nd_paused, /* ;an000; */
569 &message_type); /* ;an000; */
570 fs_build_print_message(message_type, /* ;an000; */
571 GAL_Device.device_string, /* ;an000; */
572 GAL_Target.target_fs_name, /* ;an000; */
573 GAL_Target.target_string); /* ;an000; */
574 } /* ;an000; */
575 redir_index++; /* an000; dms;next entry */ /* ;an000; */
576 inregs.x.ax = GET_ATTACH_LIST; /* an000; dms;get list of devices */ /* ;an000; */
577 inregs.x.bx = redir_index; /* an000; dms;list entry number */ /* ;an000; */
578 inregs.x.si = (unsigned int)&GAL_Device; /* an000; dms;point to device buffer */ /* ;an000; */
579 inregs.x.di = (unsigned int)&GAL_Target; /* an000; dms;point to target buffer */ /* ;an000; */
580 intdos(&inregs,&outregs); /* an000; dms;invoke call */ /* ;an000; */
581 } /* ;an000; */
582 /* ;an000; */
583 if (header_flag == FALSE) /* ;an000; */
584 Sub0_Message(NO_ENTRIES,STDOUT,Utility_Msg_Class); /* ;an000; */
585 /* ;an000; */
586 return; /* ;an000; */
587} /* ;an000; */
588 /* ;an000; */
589 /* ;an000; */
590 /* ;an000; */
591/*----------------------------------------------------------------------+
592| |
593| get_pause_stat - check the pause status of network printing or disk |
594| redirection. |
595| |
596+----------------------------------------------------------------------*/
597get_pause_stat (unsigned char type) /* ;an000; */
598 { /* ;an000; */
599 int return_flag; /* flag to return paused status */ /* ;an000; */
600 /* ;an000; */
601 inregs.x.ax = GET_PAUSE_STATUS; /* ;an000; */
602 inregs.h.bl = type; /* ;an000; */
603 intdos(&inregs, &outregs); /* ;an000; */
604 /* ;an000; */
605 if (outregs.h.bh == 0) return_flag = TRUE; /* ;an000; */
606 else return_flag = FALSE; /* ;an000; */
607 /* ;an000; */
608 return(return_flag); /* ;an000; */
609 } /* ;an000; */
610 /* ;an000; */
611 /* ;an000; */
612/*----------------------------------------------------------------------+
613| |
614| SUBROUTINE NAME: FS_ERROR |
615| |
616| SUBROUTINE FUNCTION: |
617| |
618| This routine is called to handle any error conditions that |
619| are detected by the FILESYS routines. |
620| |
621| INPUT: |
622| Error code (word) |
623| |
624| OUTPUT: |
625| The corresponding error message is displayed on the screen. |
626| (STDERR) |
627| |
628+----------------------------------------------------------------------*/
629void fs_error(int error_ax) /* error_ax holds error code */ /* ;an000; */
630 /* ;an000; */
631 { /* ;an000; */
632 inregs.x.ax = GET_EXTENDED_ERROR; /* get the extended error */ /* ;an000; */
633 inregs.x.bx = NULL; /* clear bx to signal > DOS 3.0 */ /* ;an000; */
634 intdos(&inregs, &outregs); /* INT 21h call */ /* ;an000; */
635 /* ;an000; */
636 inregs.x.ax = outregs.x.ax; /* get extended error in AX */ /* ;an000; */
637 inregs.x.bx = STDERR; /* output to standard error */ /* ;an000; */
638 inregs.x.cx = SubCnt0; /* no replaceables */ /* ;an000; */
639 inregs.h.dl = No_Input; /* no keyboard input */ /* ;an000; */
640 inregs.h.dh = Ext_Err_Class; /* extended error class */ /* ;an000; */
641 sysdispmsg(&inregs,&outregs); /* display the message */ /* ;an000; */
642 /* ;an000; */
643 return; /* ;an000; */
644 /* ;an000; */
645 } /* end of fs_error */ /* ;an000; */
646 /* ;an000; */
647/*=======================================================================*/ /* ;an000; */
648/* FS_Build_Print_Message:This routine builds the applicable message and */ /* ;an000; */
649/* prints it. */ /* ;an000; */
650/* Input : Msg_Num - The message number of the applicable */ /* ;an000; */
651/* message */ /* ;an000; */
652/* Output : The printed message */ /* ;an000; */
653/* */ /* ;an000; */
654/*=======================================================================*/ /* ;an000; */
655 /* ;an000; */
656void fs_build_print_message(msg_num, outline1, outline2, outline3) /* ;an000; */
657int msg_num; /* ;an000; */
658char *outline1; /* ;an000; */
659char *outline2; /* ;an000; */
660char *outline3; /* ;an000; */
661 /* ;an000; */
662{ /* ;an000; */
663 unsigned status; /* ;an000; */
664 unsigned char function; /* type of input function */ /* ;an000; */
665 unsigned char msg_class; /* ;an000; */
666 unsigned int message, /* message number */ /* ;an000; */
667 sub_cnt, /* num. of replaceable parameters */ /* ;an000; */
668 handle; /* display handle */ /* ;an000; */
669 /* ;an000; */
670 /* ;an000; */
671 switch (msg_num) /* what message do we have? */ /* ;an000; */
672 { /* ;an000; */
673 case PAUSE_RDR_MSG: function = No_Input; /* no keyboard input */ /* ;an000; */
674 message = PAUSE_RDR_MSG; /* message %1 REDIR %2 PAUSED */ /* ;an000; */
675 msg_class = Utility_Msg_Class; /* utility message */ /* ;an000; */
676 sub_cnt = SubCnt3; /* 2 replaceable parms */ /* ;an000; */
677 handle = STDOUT; /* display to standard out */ /* ;an000; */
678 break; /* end case statement */ /* ;an000; */
679 /* ;an000; */
680 case REDIR_MSG : function = No_Input; /* no keyboard input */ /* ;an000; */
681 message = REDIR_MSG; /* message - %1 REDIR %2 */ /* ;an000; */
682 msg_class = Utility_Msg_Class; /* utility message */ /* ;an000; */
683 sub_cnt = SubCnt3; /* 2 replaceable parms */ /* ;an000; */
684 handle = STDOUT; /* display to standard out */ /* ;an000; */
685 break; /* end case statement */ /* ;an000; */
686
687 case ERROR_RDR_MSG: function = No_Input; /* no keyboard input */ /* ;an002; */
688 message = ERROR_RDR_MSG; /* message %1 REDIR %2 ERROR */ /* ;an002; */
689 msg_class = Utility_Msg_Class; /* utility message */ /* ;an002; */
690 sub_cnt = SubCnt3; /* 2 replaceable parms */ /* ;an002; */
691 handle = STDOUT; /* display to standard out */ /* ;an002; */
692 break; /* end case statement */ /* ;an002; */
693 } /* ;an000; */
694 /* ;an000; */
695 switch(msg_num) /* what message number to print? */ /* ;an000; */
696 { /* ;an000; */
697 /* ;an000; */
698 case ERROR_RDR_MSG : /* message to print */ /* ;an002; */
699 case PAUSE_RDR_MSG : /* message to print */ /* ;an000; */
700 case REDIR_MSG : sublist[1].value = (unsigned far *)outline1; /* point to parm 1 */ /* ;an000; */
701 sublist[1].size = Sublist_Length; /* length of sublist */ /* ;an000; */
702 sublist[1].reserved = Reserved; /* reserved for future growth */ /* ;an000; */
703 sublist[1].id = 1; /* number of replaceable parm */ /* ;an000; */
704 sublist[1].flags = Char_Field_ASCIIZ+Left_Align; /* string input data */ /* ;an000; */
705 sublist[1].max_width = 5; /* default max width - unlimited */ /* ;an000; */
706 sublist[1].min_width = 5; /* min width of 1 */ /* ;an000; */
707 sublist[1].pad_char = Blank; /* pad with blanks */ /* ;an000; */
708 /* ;an000; */
709 sublist[2].value = (unsigned far *)outline2; /* point to parm 2 */ /* ;an000; */
710 sublist[2].size = Sublist_Length; /* length of sublist */ /* ;an000; */
711 sublist[2].reserved = Reserved; /* reserved for future growth */ /* ;an000; */
712 sublist[2].id = 2; /* number of replaceable parm */ /* ;an000; */
713 sublist[2].flags = Char_Field_ASCIIZ+Left_Align; /* string input data */ /* ;an000; */
714 sublist[2].max_width = 9; /* default max width - unlimited */ /* ;an000; */
715 sublist[2].min_width = 9; /* min width of 1 */ /* ;an000; */
716 sublist[2].pad_char = Blank; /* pad with blanks */ /* ;an000; */
717 /* ;an000; */
718 /* ;an000; */
719 sublist[3].value = (unsigned far *)outline3; /* ;an000; */
720 sublist[3].size = Sublist_Length; /* length of sublist */ /* ;an000; */
721 sublist[3].reserved = Reserved; /* reserved for future growth */ /* ;an000; */
722 sublist[3].id = 3; /* number of replaceable parm */ /* ;an000; */
723 sublist[3].flags = Char_Field_ASCIIZ+Left_Align; /* string input data */ /* ;an000; */
724 sublist[3].max_width = 0; /* default max width - unlimited */ /* ;an000; */
725 sublist[3].min_width = 1; /* min width of 1 */ /* ;an000; */
726 sublist[3].pad_char = Blank; /* pad with blanks */ /* ;an000; */
727 /* ;an000; */
728 inregs.x.ax = message; /* put message number in AX */ /* ;an000; */
729 inregs.x.bx = handle; /* put handle in BX */ /* ;an000; */
730 inregs.x.si = (unsigned int)&sublist[1]; /* put sublist pointer in SI */ /* ;an000; */
731 inregs.x.cx = sub_cnt; /* put sublist count in CX */ /* ;an000; */
732 inregs.h.dl = function; /* put function type in DL */ /* ;an000; */
733 inregs.h.dh = msg_class; /* put message class in DH */ /* ;an000; */
734 sysdispmsg(&inregs,&outregs); /* display the message */ /* ;an000; */
735 break; /* end case statement */ /* ;an000; */
736 } /* ;an000; */
737 return; /* ;an000; */
738} /* ;an000; */
739 /* ;an000; */
740 /* ;an000; */
741/************************************************************************/ /* ;an000; */
742/* STRING_BUILD - This routine takes a buffer filled with */ /* ;an000; */
743/* multiple ASCIIZ strings and concatenates them */ /* ;an000; */
744/* into one string by convering all null chars. */ /* ;an000; */
745/* to a blank. */ /* ;an000; */
746/* */ /* ;an000; */
747/* Inputs - GAL_Target (struct) */ /* ;an000; */
748/* */ /* ;an000; */
749/* Outputs - converted buffer */ /* ;an000; */
750/* */ /* ;an000; */
751/************************************************************************/ /* ;an000; */
752 /* ;an000; */
753void string_build() /* ;an000; */
754 /* ;an000; */
755{ /* ;an000; */
756 int x; /* ;an000; */
757 int i; /* ;an000; */
758 /* ;an000; */
759 x = 0; /* an000; dms;index pointer */ /* ;an000; */
760 i = 0; /* an000; dms;loop counter */ /* ;an000; */
761 while (i != GAL_Target.target_count) /* an000; dms;while strings exist */ /* ;an000; */
762 { /* ;an000; */
763 while (GAL_Target.target_string[x] != NULL) /* an000; dms;while not end of string */ /* ;an000; */
764 x++; /* an000; dms;increment pointer */ /* ;an000; */
765 GAL_Target.target_string[x] = Blank; /* an000; dms;blank terminate string */ /* ;an000; */
766 x++; /* an000; dms;increment pointer */ /* ;an000; */
767 i++; /* an000; dms;next string */ /* ;an000; */
768 } /* ;an000; */
769 GAL_Target.target_string[x] = NULL; /* an000; null terminate buffer */ /* ;an000; */
770 return; /* ;an000; */
771} /* ;an000; */
772 /* ;an000; */
773 /* ;an000; */
774/************************************************************************/ /* ;an000; */
775/* CHECK_PAUSE_STATUS - This routine determines if the net drive or */ /* ;an000; */
776/* printer is paused. */ /* ;an000; */
777/* */ /* ;an000; */
778/* Inputs : regbl - contents of register BL */ /* ;an000; */
779/* dr_pause - driver pause flag */ /* ;an000; */
780/* pr_pause - printer pause flag */ /* ;an000; */
781/* net_flag - signals 1st. occurrence */ /* ;an000; */
782/* */ /* ;an000; */
783/* Outputs : dr_pause - flag set appropriately */ /* ;an000; */
784/* pr_pause - flag set appropriately */ /* ;an000; */
785/* net_flag - flag set appropriately */ /* ;an000; */
786/* */ /* ;an000; */
787/************************************************************************/ /* ;an000; */
788 /* ;an000; */
789void check_pause_status(regbl, pr_pause, dr_pause, net_flag) /* ;an001; */
790 /* ;an000; */
791 unsigned char regbl; /* ;an000; */
792 int *dr_pause; /* ;an000; */
793 int *pr_pause; /* ;an000; */
794 int *net_flag; /* ;an000; */
795{ /* ;an000; */
796 if (((regbl == NET_PRINTER) || /* an000; dms; if net drive or printer */ /* ;an000; */
797 (regbl == NET_DRIVE)) && /* ;an001; */
798 (*net_flag == TRUE)) /* ;an001; */
799 { /* ;an000; */
800 *net_flag = FALSE; /* an000; dms; set flag to false */ /* ;an001; */
801 *pr_pause = get_pause_stat(NET_PRINTER); /* an000; dms; see if printer paused */ /* ;an000; */
802 *dr_pause = get_pause_stat(NET_DRIVE); /* an000; dms; see if drive paused */ /* ;an000; */
803 } /* ;an000; */
804 return; /* ;an000; */
805} /* ;an000; */
806 /* ;an000; */
807 /* ;an000; */
808/************************************************************************/ /* ;an000; */
809/* PRINT_STATUS - This routine determines the type of print */ /* ;an000; */
810/* message that is to be used. */ /* ;an000; */
811/* */ /* ;an000; */
812/* Inputs : entry_type - type of device */ /* ;an000; */
813/* np_paused - flag */ /* ;an000; */
814/* nd_paused - flag */ /* ;an000; */
815/* message_type - type of message to print */ /* ;an000; */
816/* */ /* ;an000; */
817/* Outputs : message_type - message type to be printed */ /* ;an000; */
818/* */ /* ;an000; */
819/************************************************************************/ /* ;an000; */
820 /* ;an000; */
821void print_status(entry_type, np_paused, nd_paused, message_type) /* ;an000; */
822 /* ;an000; */
823 int entry_type; /* ;an000; */
824 int np_paused; /* ;an000; */
825 int nd_paused; /* ;an000; */
826 int *message_type; /* ;an000; */
827{ /* ;an000; */
828 if ((entry_type == NET_PRINTER) && (np_paused == TRUE)) /* ;an000; */
829 *message_type = PAUSE_RDR_MSG; /* ;an000; */
830 else /* printing not paused, try disk redir */ /* ;an000; */
831 { /* ;an000; */
832 if ((entry_type == NET_DRIVE) && (nd_paused == TRUE)) /* ;an000; */
833 *message_type = PAUSE_RDR_MSG; /* ;an000; */
834 else /* ;an000; */
835 *message_type = REDIR_MSG; /* ;an000; */
836 } /* ;an000; */
837 /* ;an000; */
838 if (entry_type == NET_PRINTER) /* always want to add ":" to LPTx */ /* ;an000; */
839 strncat(GAL_Device.device_string,":",1); /* ;an000; */
840 /* ;an000; */
841 return; /* ;an000; */
842} /* ;an000; */
843 /* ;an000; */
844 /* ;an000; */
845/************************************************************************/ /* ;an000; */
846/* SUB0_MESSAGE - This routine will print only those */ /* ;an000; */
847/* messages that do not require a */ /* ;an000; */
848/* a sublist. */ /* ;an000; */
849/* */ /* ;an000; */
850/* Inputs : Msg_Num - number of applicable message */ /* ;an000; */
851/* Handle - display type */ /* ;an000; */
852/* Message_Type - type of message to display */ /* ;an000; */
853/* */ /* ;an000; */
854/* Outputs : message */ /* ;an000; */
855/* */ /* ;an000; */
856/************************************************************************/ /* ;an000; */
857 /* ;an000; */
858void Sub0_Message(Msg_Num,Handle,Message_Type) /* print messages with no subs */ /* ;an000; */
859 /* ;an000; */
860int Msg_Num; /* ;an000; */
861int Handle; /* ;an000; */
862unsigned char Message_Type; /* ;an000; */
863 /* extended, parse, or utility */ /* ;an000; */
864 { /* ;an000; */
865 inregs.x.ax = Msg_Num; /* put message number in AX */ /* ;an000; */
866 inregs.x.bx = Handle; /* put handle in BX */ /* ;an000; */
867 inregs.x.cx = No_Replace; /* no replaceable subparms */ /* ;an000; */
868 inregs.h.dl = No_Input; /* no keyboard input */ /* ;an000; */
869 inregs.h.dh = Message_Type; /* type of message to display */ /* ;an000; */
870 sysdispmsg(&inregs,&outregs); /* display the message */ /* ;an000; */
871 /* ;an000; */
872 return; /* ;an000; */
873 } /* ;an000; */
874 /* ;an000; */
875/************************************************************************/ /* ;an000; */
876/* FS_STRCPY - This routine will provide the string copy */ /* ;an000; */
877/* capability for a far pointer. */ /* ;an000; */
878/* */ /* ;an000; */
879/* Inputs : buffer - pointer to the destination */ /* ;an000; */
880/* parse_ptr - far pointer to source */ /* ;an000; */
881/* */ /* ;an000; */
882/* Outputs : buffer - new string */ /* ;an000; */
883/* */ /* ;an000; */
884/************************************************************************/ /* ;an000; */
885 /* ;an000; */
886void fs_strcpy(buffer, parse_ptr) /* ;an000; */
887 /* ;an000; */
888 char *buffer; /* ;an000; */
889 char far *parse_ptr; /* ;an000; */
890 /* ;an000; */
891 { /* ;an000; */
892 /* ;an000; */
893 while ((*buffer = *parse_ptr) != NULL) /* ;an000; */
894 { /* ;an000; */
895 buffer++; /* ;an000; */
896 parse_ptr++; /* ;an000; */
897 } /* ;an000; */
898 return; /* ;an000; */
899 } /* ;an000; */
900 /* ;an000; */
901 /* ;an000; */
902/************************************************************************/ /* ;an000; */
903/* FS_STRLEN - This routine calculates the string's length. */ /* ;an000; */
904/* */ /* ;an000; */
905/* Inputs : parse_ptr - pointer to the string to measure */ /* ;an000; */
906/* */ /* ;an000; */
907/* Outputs : i - string's length */ /* ;an000; */
908/* */ /* ;an000; */
909/************************************************************************/ /* ;an000; */
910 /* ;an000; */
911int fs_strlen(parse_ptr) /* ;an000; */
912 /* ;an000; */
913 char far *parse_ptr; /* ;an000; */
914 /* ;an000; */
915 { /* ;an000; */
916 int i; /* ;an000; */
917 /* ;an000; */
918 for (i = 0; *parse_ptr != NULL; parse_ptr++) /* ;an000; */
919 i++; /* ;an000; */
920 /* ;an000; */
921 return(i); /* ;an000; */
922 } /* ;an000; */