|
|
1.1 root 1: /* cvmodem.c: convert /etc/modemcap to dial file for Taylor uucp.
2: *
3: * Read a modemcap entry, parse out modem names, cs, ce, is and hu strings
4: * and build dial chat, dial-abort chat and dial-complete chat.
5: */
6:
7: #include <stdio.h>
8: #include <string.h>
9:
10: #define MODEMCAP "/etc/modemcap"
11: #define DIAL "/usr/lib/uucp/dial"
12: #define MAXLEN 125
13:
14: /* flags for get_cmd() */
15:
16: #define IS 1
17: #define HU 2
18: #define CS 3
19: #define CE 4
20: #define DS 5
21: #define CO 6
22:
23: char cs_cmd[MAXLEN]; /* command start string */
24: char ce_cmd[MAXLEN]; /* command end string */
25: char ds_cmd[MAXLEN]; /* command to start dialing */
26: char is_cmd[MAXLEN]; /* setup modem to dial */
27: char hu_cmd[MAXLEN]; /* hang up and reset modem registers */
28: char co_cmd[MAXLEN]; /* expected connect message when modem connects */
29:
30: FILE *infp; /* pointer to MODEMCAP file */
31:
32: int get_cap(); /* get a modemcap entry */
33: int get_cmd(); /* parse command string from modemcap entry */
34: int bld_dial(); /* build dial file entry */
35:
36: main()
37: {
38: int get_stat = 0; /* status of get_cap() */
39:
40:
41: if( (infp=fopen(MODEMCAP,"r")) == NULL){
42: printf("Failed to open file %s!\n",MODEMCAP);
43: exit(1);
44: }
45:
46: do{
47: get_stat = get_cap();
48: /* printf("get_cap() returned [%d]\n",get_stat); */
49: }
50: while (get_stat == 0);
51:
52: fclose(infp);
53:
54: }
55:
56: /* get_cap(): read a modemcap entry, copying the modemcap entry identifies
57: * (list of modem names) to a string to be parsed. Copy modemcap
58: * command lines to a string and parse out what we need to build
59: * our dial file entry.
60: */
61:
62: int get_cap()
63: {
64:
65: char *list_ptr; /* pointer to modem name list */
66: char *name_ptr; /* pointer to individual modem name */
67: char *cmd_ptr; /* pointer to command within modemcap command
68: * line.
69: */
70: char mdm_names[81]; /* modemcap line with modem names */
71: char mdm_entry[25]; /* single modem name parsed from mdm_names */
72: char work_line[81]; /* dummy: all lines read to here first to
73: * determine what we read.
74: */
75:
76: short hu_flag = 0; /* flags to see what we've already scanned for */
77: short is_flag = 0;
78: short cs_flag = 0;
79: short ce_flag = 0;
80: short ds_flag = 0;
81: short co_flag = 0;
82:
83: /* initialize our commands to build */
84: strcpy(is_cmd,"");
85: strcpy(hu_cmd,"");
86: strcpy(cs_cmd,"");
87: strcpy(ce_cmd,"");
88: strcpy(ds_cmd,"");
89: strcpy(co_cmd,"");
90:
91: do{
92: if(fgets(work_line, MAXLEN, infp) == NULL){
93: return(1);
94: }
95: /* skip comments and blank lines */
96: if( (work_line[0]=='#') || (work_line[0] == '\n'))
97: continue;
98:
99: /* if not a tab, it isn't a comment (we just tested for that)
100: * and therefore must be the first valid line of a modemcap
101: * entry which gives the modem names.
102: */
103:
104: if( (work_line[0] != '\t') && (work_line[0] != ' ')){
105: strcpy(mdm_names, work_line);
106: strcpy(work_line, "");
107: continue;
108: }
109:
110:
111: /* If we got this far, then we must be looking at a modemcap
112: * line listing commands.
113: */
114:
115: /* look for our cu, hu... commands */
116:
117: if(strlen(mdm_names) > 0){
118:
119: if((cmd_ptr = (strstr(work_line,":is"))) != NULL)
120: if(get_cmd(IS, cmd_ptr))
121: is_flag = 1;
122: else{
123: printf("An invalid initialization string (is:) was detected in the modemcap file.\n");
124: printf("This program will now exit, please examine this line:\n");
125: printf("%s",work_line);
126: exit(1);
127: }
128: if((cmd_ptr = (strstr(work_line,":hu"))) != NULL)
129: if(get_cmd(HU, cmd_ptr))
130: hu_flag = 1;
131: else{
132: printf("An invalid hangup command string (hu:) was detected in the modemcap file.\n");
133: printf("This program will now exit, please examine this line:\n");
134: printf("%s",work_line);
135: exit(1);
136: }
137: if((cmd_ptr = (strstr(work_line,":cs"))) != NULL)
138: if(get_cmd(CS, cmd_ptr))
139: cs_flag = 1;
140: else{
141: printf("An invalid command start string (cs:) was detected in the modemcap file.\n");
142: printf("This program will now exit, please examine this line:\n");
143: printf("%s",work_line);
144: exit(1);
145: }
146: if((cmd_ptr = (strstr(work_line,":ce"))) != NULL)
147: if(get_cmd(CE, cmd_ptr))
148: ce_flag = 1;
149: else{
150: printf("An invalid command end string (ce:) was detected in the modemcap file.\n");
151: printf("This program will now exit, please examine this line:\n");
152: printf("%s",work_line);
153: exit(1);
154: }
155: if((cmd_ptr = (strstr(work_line,":ds"))) != NULL)
156: if(get_cmd(DS, cmd_ptr))
157: ds_flag = 1;
158: else{
159: printf("An invalid start dial string (ds:) was detected in the modemcap file.\n");
160: printf("This program will now exit, please examine this line:\n");
161: printf("%s",work_line);
162: exit(1);
163: }
164:
165: /* a null connect message is valid, so we don't
166: * necessarily care about what get_cmd returned.
167: */
168: if((cmd_ptr = (strstr(work_line,":co"))) != NULL){
169: get_cmd(CO, cmd_ptr);
170: co_flag = 1;
171: }
172: }else{
173: continue;
174: }
175: }
176: while( hu_flag + is_flag + ce_flag + cs_flag + ds_flag + co_flag != 6);
177:
178: /* printf("%s",mdm_names);
179: printf("is: %s\n", is_cmd);
180: printf("hu: %s\n", hu_cmd);
181: printf("cs: %s\n", cs_cmd);
182: printf("ce: %s\n", ce_cmd);
183: printf("ds: %s\n", ds_cmd);
184: printf("co: %s\n", co_cmd);
185: */
186:
187: /* parse out our individual modem names from the list of names
188: * in the modem name list, then call the function to write the
189: * data into the dial file as a completed dial entry. Remember,
190: * we only want to do this if we have found all of the data we
191: * need from the entry in the modemcap file.
192: */
193:
194: list_ptr = mdm_names; /* initialize our single entry string and */
195: strcpy(mdm_entry,""); /* set up our pointers. */
196:
197:
198: if (hu_flag && is_flag && ce_flag && cs_flag && ds_flag && co_flag ){
199: do{
200: name_ptr = mdm_entry;
201: while(*list_ptr != '|'){ /* copy our name, stoping at | */
202: /* printf("[%c]",*list_ptr); */
203: if( (*list_ptr == ' ') || (*list_ptr =='\\') )
204: return(0); /* abort on space */
205: *name_ptr++ = *list_ptr++;
206: }
207: list_ptr++; /* skip | */
208: *name_ptr = '\0'; /* terminate name string */
209: bld_dial(mdm_entry);
210: /* printf("Single modem: %s\n",mdm_entry); */
211: strcpy(mdm_entry,"");
212: }
213: while( (*list_ptr != ' ') && (*list_ptr != '\\'));
214: strcpy(mdm_names,"");
215: return(0);
216: }else{
217: return(1);
218: }
219:
220: }
221:
222:
223:
224: /* get_cmd() will take a pointer to a string, a pointer to where to
225: * begin parsing an entry out of a string and a flag to tell us what
226: * what command we are parsing.
227: */
228:
229: int get_cmd(flag, pointer)
230: int flag; /* flag for command string we're working with */
231: char *pointer; /* where to start our search withing the work string */
232:
233: {
234:
235: char *cmdptr; /* pointer to command string */
236:
237: /* look at the flag passed and set our pointer accordingly */
238:
239:
240: switch(flag){
241: case IS: /* modem initialization string to dial out */
242: cmdptr = is_cmd;
243: break;
244: case HU: /* modem hangup string and reset cmds */
245: cmdptr = hu_cmd;
246: break;
247: case CS: /* command start string */
248: cmdptr = cs_cmd;
249: break;
250: case CE: /* command terminator string */
251: cmdptr = ce_cmd;
252: break;
253: case DS: /* modem dial command */
254: cmdptr = ds_cmd;
255: break;
256: case CO: /* modem connect message */
257: cmdptr = co_cmd;
258: break;
259: default:
260: printf("Unknown command flag received [%d]\n",flag);
261: return;
262: }
263:
264: pointer+=4; /* get past the '=' in command entry */
265:
266:
267: /* we begin copying from the curreent position in the work_line,
268: * as this is SUPPOSED to be the start of the command. When we
269: * hit a SPACE, we convert it to a \s, as required by Taylor's
270: * modem chat configuration.
271: */
272:
273: while(*pointer != ':'){
274: if(*pointer == ' '){
275: *cmdptr++ = '\\';
276: *cmdptr++ = 's';
277: pointer++;
278: continue;
279: }
280: *cmdptr++ = *pointer++;
281: }
282: *cmdptr = '\0'; /* terminate our string */
283:
284: if(flag == IS){ /* an is: ends with a \r (carriage */
285: cmdptr--; /* return). We change the 'r' to an */
286: *cmdptr = 's'; /* 's' to make it look like a space.*/
287: }
288:
289: /* if we went through all of this and came up with a command string
290: * of 0 length, then an invalid modemcap entry exists. We will
291: * return a 0 in this case, which will serve as a flag to
292: * abort the process of converting the current and remaining
293: * modemcap entries.
294: */
295:
296: switch(flag){
297: case IS: /* modem initialization string to dial out */
298: /* printf("is -x %s\n", is_cmd); */
299: if(strlen(is_cmd) > 0)
300: return 1;
301: else
302: return 0;
303: /* not reached */
304: case HU: /* modem hangup string and reset cmds */
305: /* printf("hu -x %s\n", hu_cmd); */
306: if(strlen(hu_cmd) > 0)
307: return 1;
308: else
309: return 0;
310: /* not reached */
311: case CS: /* command start string */
312: /* printf("cs -x %s\n", cs_cmd); */
313: if(strlen(cs_cmd) > 0)
314: return 1;
315: else
316: return 0;
317: /* not reached */
318: case CE: /* command terminator string */
319: /* printf("ce -x %s\n", ce_cmd); */
320: if(strlen(ce_cmd) > 0)
321: return 1;
322: else
323: return 0;
324: /* not reached */
325: case DS: /* modem dial command */
326: /* printf("ds -x %s\n", ds_cmd); */
327: if(strlen(ds_cmd) > 0)
328: return 1;
329: else
330: return 0;
331: /* not reached */
332: case CO: /* modem connect message... NULL is valid */
333: return 1;
334: /* not reached */
335: }
336:
337: }
338:
339: /* bld_dial(): given a name of a modem, take the cs, is, ds, cs and
340: * co information and write out a dial file entry.
341: */
342:
343: bld_dial(name)
344: char * name; /* name of modem */
345: {
346: FILE *outfile;
347:
348: /* open the file for append, abort on error */
349: if((outfile=fopen(DIAL,"a")) == NULL){
350: printf("Failed to open %s to append new entry for modem {%s}\n",
351: DIAL, name);
352: exit(1);
353: }
354:
355:
356: /* name of our dialer */
357: fprintf(outfile,"dialer %s\n",name);
358:
359: /* dialer chat */
360: fprintf(outfile,"chat \"\" %s%s\\D %s\n",
361: is_cmd, ds_cmd,co_cmd);
362:
363: /* some default stuff... timeout before failing and chat failure
364: * detection.
365: */
366:
367: fprintf(outfile,"chat-timeout 60\n");
368: fprintf(outfile,"chat-fail BUSY\n");
369: fprintf(outfile,"chat-fail NO\\sCARRIER\n");
370: fprintf(outfile,"chat-fail NO\\sANSWER\n");
371:
372: /* the following is a modem chat script to be done if a call
373: * is successful and uucico runs smoothly.
374: */
375:
376: fprintf(outfile,"complete-chat \"\" \\d+++\\d%s%s\n",
377: cs_cmd, hu_cmd);
378:
379: /* the following is a modem chat script to be done is a call
380: * is NOT successful. This is the same chat for successful calls
381: * as a default for the purpose of converting modemcap entries.
382: */
383:
384: fprintf(outfile,"abort-chat \"\" \\d+++\\d%s%s\n\n",
385: cs_cmd, hu_cmd);
386:
387: /* close our file */
388:
389: fclose(outfile);
390: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.