Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / usr.sbin / i4b / isdnphone / main.c
1 /*
2  * Copyright (c) 1999, 2001 Hellmuth Michaelis. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  *---------------------------------------------------------------------------
26  *
27  *      isdnphone - main module
28  *      =======================
29  *
30  *      $Id: main.c,v 1.12 1999/12/13 21:25:26 hm Exp $
31  *
32  * $FreeBSD: src/usr.sbin/i4b/isdnphone/main.c,v 1.1.2.2 2001/12/16 15:13:38 hm Exp $
33  * $DragonFly: src/usr.sbin/i4b/isdnphone/main.c,v 1.2 2003/06/17 04:29:55 dillon Exp $
34  *
35  *      last edit-date: [Mon Dec 13 21:53:25 1999]
36  *
37  *---------------------------------------------------------------------------*/
38
39 #define MAIN
40 #include "defs.h"
41
42 static void kbd_hdlr(void);
43
44 /*---------------------------------------------------------------------------*
45  *      usage display and exit
46  *---------------------------------------------------------------------------*/
47 static void
48 usage(void)
49 {
50         fprintf(stderr, "\n");
51         fprintf(stderr, "isdnphone - i4b phone program, version %d.%d.%d, compiled %s %s\n",VERSION, REL, STEP, __DATE__, __TIME__);
52         fprintf(stderr, "usage: isdnphone -d -h -k <string> -n <number> -u <unit>\n");
53         fprintf(stderr, "       -d            debug\n");
54         fprintf(stderr, "       -h            hangup\n");
55         fprintf(stderr, "       -k string     keypad string\n");
56         fprintf(stderr, "       -n number     dial number\n");
57         fprintf(stderr, "       -u unit       set unit number\n");
58         fprintf(stderr, "\n");
59         exit(1);
60 }
61
62 /*---------------------------------------------------------------------------*
63  *      program entry
64  *---------------------------------------------------------------------------*/
65 int
66 main(int argc, char **argv)
67 {
68         int c;
69         char namebuffer[128];
70         int bschar;
71         int ret;
72         int opt_n = 0;
73         int opt_h = 0;
74         int opt_k = 0;
75         char *number = "";
76         
77         numberbuffer[0] = '\0'; 
78
79         while ((c = getopt(argc, argv, "dhk:n:u:")) != -1)
80         {
81                 switch(c)
82                 {
83                         case 'd':
84                                 opt_d = 1;
85                                 break;
86                                 
87                         case 'h':
88                                 opt_h = 1;
89                                 break;
90                                 
91                         case 'k':
92                                 number = optarg;
93                                 opt_k = 1;
94                                 break;
95                                 
96                         case 'n':
97                                 number = optarg;
98                                 opt_n = 1;
99                                 break;
100                                 
101                         case 'u':
102                                 opt_unit = atoi(optarg);
103                                 if(opt_unit < 0 || opt_unit > 9)
104                                         usage();
105                                 break;
106
107                         case '?':
108                         default:
109                                 usage();
110                                 break;
111                 }
112         }
113
114         sprintf(namebuffer,"%s%d", I4BTELDDEVICE, opt_unit);
115         
116         if((dialerfd = init_dial(namebuffer)) == -1)
117                 exit(1);
118
119         if(opt_n || opt_h || opt_k)
120         {
121                 char commandbuffer[80];
122                 
123                 /* commandline operation goes here */
124                 
125                 if(opt_n)
126                 {
127                         sprintf(commandbuffer, "D%s", number);
128         
129                 }
130                 else if(opt_k)
131                 {
132                         sprintf(commandbuffer, "K%s", number);
133         
134                 }
135                 else if(opt_h)
136                 {
137                         sprintf(commandbuffer, "H");
138                 }
139         
140                 if((ret = write(dialerfd, commandbuffer, strlen(commandbuffer))) < 0)
141                 {
142                         fprintf(stderr, "write commandbuffer failed: %s", strerror(errno));
143                         exit(1);
144                 }
145         
146                 close(dialerfd);
147                 
148                 exit(0);
149         }
150
151         if((audiofd = init_audio(AUDIODEVICE)) == -1)
152                 exit(1);
153         
154         /* fullscreen operation here */ 
155
156         init_mainw();
157
158         bschar = erasechar();
159         curx = 0;
160
161         wmove(main_w, MW_NUMY, MW_NUX + curx);
162         
163         /* go into loop */
164
165         for (;;)
166         {
167                 int maxfd = 0;
168                 fd_set set;
169                 struct timeval timeout;
170
171                 FD_ZERO(&set);
172                 
173                 FD_SET(STDIN_FILENO, &set);
174                 if(STDIN_FILENO > maxfd)
175                         maxfd = STDIN_FILENO;
176                 
177                 FD_SET(dialerfd, &set);
178                 if(dialerfd > maxfd)
179                         maxfd = dialerfd;
180                 
181                 if(state == ST_ACTIVE)
182                 {
183                         if(audiofd != -1)
184                         {
185                                 FD_SET(audiofd, &set);
186                                 if(audiofd > maxfd)
187                                         maxfd = audiofd;
188                         }
189                         
190                         if(telfd != -1)
191                         {
192                                 FD_SET(telfd, &set);
193                                 if(telfd > maxfd)
194                                         maxfd = telfd;
195                         }
196                 }
197                 
198                 timeout.tv_sec = 2;
199                 timeout.tv_usec = 0;
200
201                 wrefresh(main_w);
202                 
203                 /* if no char is available within timeout, do something */
204                 
205 #ifdef NOTDEF
206                 ret = select(maxfd+1, &set, NULL, NULL, &timeout);
207 #else
208                 ret = select(maxfd+1, &set, NULL, NULL, NULL);
209 #endif
210
211                 if(ret > 0)
212                 {
213                         if((telfd != -1) && (FD_ISSET(telfd, &set)))
214                         {
215                                 message("select from ISDN");
216                                 tel_hdlr();
217                         }
218                         if((audiofd != -1) && (FD_ISSET(audiofd, &set)))
219                         {
220                                 message("select from audio");
221                                 audio_hdlr();
222                         }
223                         if(FD_ISSET(dialerfd, &set))
224                         {
225                                 message("select from tel");
226                                 dial_hdlr();
227                         }
228                         if(FD_ISSET(STDIN_FILENO, &set))
229                         {
230                                 message("select from kbd");
231                                 kbd_hdlr();
232                         }
233                 }
234         }
235         do_quit(0);
236         
237         return(0);
238 }
239
240 /*---------------------------------------------------------------------------*
241  *      keyboard character available handler
242  *---------------------------------------------------------------------------*/
243 static void
244 kbd_hdlr(void)
245 {               
246         int kchar;
247
248         kchar = wgetch(main_w);         /* get char */
249                                 
250         switch (kchar)
251         {
252                 case CR:
253                 case LF:
254 #ifdef KEY_ENTER
255                 case KEY_ENTER:
256 #endif
257                         if((state == ST_IDLE) &&
258                            (numberbuffer[0] != '\0'))
259                         {
260                                 message("dialing .....");
261                                 do_dial(&numberbuffer[0]);
262                         }
263                         else
264                         {
265                                 do_menu();
266                         }
267                         break;
268
269                 case CNTRL_D:
270                         if(state == ST_IDLE)
271                         {
272                                 do_quit(0);
273                         }
274                         else
275                         {
276                                 message("cannot exit while not idle!");
277                                 beep();
278                         }
279                         
280                         break;
281
282                 case CNTRL_L:   /* refresh */
283                         touchwin(curscr);
284                         wrefresh(curscr);
285                         break;
286
287                 case KEY_BACKSPACE:
288                 case KEY_DC:
289                         if (curx == 0)
290                                 break;
291
292                         curx--;
293                         mvwaddch(main_w, MW_NUMY, MW_NUX + curx, ' ');
294                         numberbuffer[curx] = '\0';
295                         wmove(main_w, MW_NUMY, MW_NUX + curx);
296
297                         if(curx == 0)
298                                 message(" ");
299                         
300                         break;
301                         
302                 case '0':
303                 case '1':
304                 case '2':
305                 case '3':
306                 case '4':
307                 case '5':
308                 case '6':
309                 case '7':
310                 case '8':
311                 case '9':
312                         if(curx > (TELNO_MAX-1))
313                                 break;
314
315                         mvwaddch(main_w, MW_NUMY, MW_NUX + curx, kchar);
316                         
317                         numberbuffer[curx] = kchar;
318
319                         curx++;
320
321                         numberbuffer[curx] = '\0';
322                         
323                         message("press ENTER to dial number .....");
324                         break;
325         }
326 }
327
328 /*---------------------------------------------------------------------------*
329  *      exit program
330  *---------------------------------------------------------------------------*/
331 void
332 do_quit(int exitval)
333 {
334         close(dialerfd);
335         move(LINES-1, 0);
336         clrtoeol();
337         refresh();
338         endwin();
339         exit(exitval);
340 }
341
342 /*---------------------------------------------------------------------------*
343  *      fatal error exit
344  *---------------------------------------------------------------------------*/
345 void
346 fatal(char *fmt, ...)
347 {
348         va_list ap;
349
350         va_start(ap, fmt);
351
352         do_hangup();            /* failsafe */
353         
354         if(curses_ready)
355         {       
356                 close(dialerfd);
357                 move(LINES-1, 0);
358                 clrtoeol();
359                 refresh();
360                 endwin();
361         }
362
363         fprintf(stderr, "\nFatal error: ");
364         vfprintf(stderr, fmt, ap);
365         fprintf(stderr, "\n\n");
366                 
367         va_end(ap);
368
369         exit(1);
370 }
371
372 /*---------------------------------------------------------------------------*
373  *      message printing
374  *---------------------------------------------------------------------------*/
375 void
376 message(char *fmt, ...)
377 {
378         va_list ap;
379
380         va_start(ap, fmt);
381
382         if(curses_ready)
383         {
384                 int i;
385                 char sbuf[MW_WIDTH];
386                 
387                 wmove(main_w, MW_MSGY, MW_MSX);
388                 vsnprintf(sbuf, MW_WIDTH-MW_MSX-1, fmt, ap);
389                 waddstr(main_w, sbuf);
390                 for(i=strlen(sbuf);i < MW_WIDTH-MW_MSX-2; i++)
391                         waddch(main_w, ' ');
392                 wmove(main_w, MW_NUMY, MW_NUX + curx);                  
393                 wrefresh(main_w);
394         }
395         else
396         {
397                 fprintf(stderr, "ERROR: ");
398                 vfprintf(stderr, fmt, ap);
399                 fprintf(stderr, "\n");
400         }
401                 
402         va_end(ap);
403 }
404
405 /*---------------------------------------------------------------------------*
406  *      message printing
407  *---------------------------------------------------------------------------*/
408 void
409 debug(char *fmt, ...)
410 {
411         va_list ap;
412
413         if(opt_d == 0)
414                 return;
415                 
416         va_start(ap, fmt);
417
418         vwprintw(dbg_w, fmt, ap);
419         wrefresh(dbg_w);
420                 
421         va_end(ap);
422 }
423
424 /*---------------------------------------------------------------------------*
425  *      go to new state
426  *---------------------------------------------------------------------------*/
427 void
428 newstate(int newstate)
429 {
430         int i;
431         
432         if(newstate < 0 || newstate > ST_MAX)
433         {
434                 message("newstate %d undefined!", newstate);
435                 return;
436         }
437
438         state = newstate;
439
440         if(newstate == ST_ACTIVE)
441         {
442                 char namebuffer[128];
443                 
444                 sprintf(namebuffer,"%s%d", I4BTELDEVICE, opt_unit);
445                 telfd = init_tel(namebuffer);
446         }
447
448         if(newstate == ST_IDLE)
449         {
450                 close(telfd);
451                 telfd = -1;
452         }
453         
454         wmove(main_w, MW_STATEY, MW_STX);
455         waddstr(main_w, states[newstate]);
456
457         for(i=strlen(states[newstate]);i < MW_WIDTH-MW_STX-2; i++)
458                 waddch(main_w, ' ');
459
460         wmove(main_w, MW_NUMY, MW_NUX + curx);                  
461         wrefresh(main_w);
462 }
463
464 /* EOF */