]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/CMD/FILESYS/FILESYS.C

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / CMD / FILESYS / FILESYS.C
1 /* \ f */
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; */
69 void main(int, char *[]); /* ;an000; */
70 void parse_init(void); /* ;an000; */
71 void device_attach(int, char *, char *, char *); /* ;an000; */
72 void device_detach(char *); /* ;an000; */
73 void fs_status(char *); /* ;an000; */
74 int get_pause_stat(unsigned char); /* ;an000; */
75 void fs_error(int); /* ;an000; */
76 void fs_build_print_message(int, char *, char *, char *); /* ;an000; */
77 void string_build(void); /* ;an000; */
78 void check_pause_status(unsigned char, int *, int *, int *); /* ;an000; */
79 void print_status(int, int, int, int *); /* ;an000; */
80 void Sub0_Message(int,int,unsigned char); /* ;an000; */
81 void fs_strcpy(char *, char far *); /* ;an000; */
82 int fs_strlen(char far *); /* ;an000; */
83 /* ;an000; */
84 extern void sysloadmsg(union REGS *, union REGS *); /* ;an000; */
85 extern void sysdispmsg(union REGS *, union REGS *); /* ;an000; */
86 extern void parse(union REGS *, union REGS *); /* ;an000; */
87 /* ;an000; */
88 /* ;an000; */
89 struct p_parms p_p; /* ;an000; */
90 struct p_parms p_p1; /* ;an000; */
91 /* ;an000; */
92 struct p_parmsx p_px; /* ;an000; */
93 struct p_parmsx p_px1; /* ;an000; */
94 /* ;an000; */
95 struct p_control_blk p_con1; /* ;an000; */
96 struct p_control_blk p_con1a; /* ;an000; */
97 struct p_control_blk p_con2; /* ;an000; */
98 struct p_control_blk p_con3; /* ;an000; */
99 struct p_control_blk p_con4; /* ;an000; */
100 /* ;an000; */
101 struct p_control_blk p_swt1; /* ;an000; */
102 /* ;an000; */
103 struct p_result_blk p_result1; /* ;an000; */
104 struct p_result_blk_D p_resultD; /* ;an000; */
105 /* ;an000; */
106 /* ;an000; */
107 struct p_value_blk p_noval; /* ;an000; */
108 /* ;an000; */
109 /* ;an000; */
110 char cmd_line[128]; /* ;an000; */
111 char 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; */
128 struct /* ;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; */
135 struct /* ;an000; */
136 { /* ;an000; */
137 char device_string[9]; /* ;an000; */
138 } GAL_Device; /* ;an000; */
139 /* ;an000; */
140 /* ;an000; */
141 struct /* ;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 +----------------------------------------------------------------------*/
152 union REGS inregs, outregs; /* ;an000; */
153 struct SREGS segregs; /* ;an000; */
154 /* ;an000; */
155 \f /* ;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; */
164 void main(argc,argv) /* ;an000; */
165 /* ;an000; */
166 int argc; /* number of arguments passed on command line */ /* ;an000; */
167 char *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 \f /* ;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 +----------------------------------------------------------------------*/
306 void 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 \f /* ;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 +----------------------------------------------------------------------*/
410 void 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 \f /* ;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 +----------------------------------------------------------------------*/
458 void 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 \f /* ;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 +----------------------------------------------------------------------*/
479 void 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 \f /* ;an000; */
591 /*----------------------------------------------------------------------+
592 | |
593 | get_pause_stat - check the pause status of network printing or disk |
594 | redirection. |
595 | |
596 +----------------------------------------------------------------------*/
597 get_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 \f /* ;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 +----------------------------------------------------------------------*/
629 void 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; */
656 void fs_build_print_message(msg_num, outline1, outline2, outline3) /* ;an000; */
657 int msg_num; /* ;an000; */
658 char *outline1; /* ;an000; */
659 char *outline2; /* ;an000; */
660 char *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; */
753 void 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; */
789 void 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; */
821 void 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; */
858 void Sub0_Message(Msg_Num,Handle,Message_Type) /* print messages with no subs */ /* ;an000; */
859 /* ;an000; */
860 int Msg_Num; /* ;an000; */
861 int Handle; /* ;an000; */
862 unsigned 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; */
886 void 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; */
911 int 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; */