some small conference jingle fixes
[lcr.git] / extension.c
1 /*****************************************************************************\
2 **                                                                           **
3 ** PBX4Linux                                                                 **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** reading and writing files for extensions                                  **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12 #include "main.h"
13
14 /* extension */
15
16 char *ext_rights[] = {
17         "none",
18         "internal",
19         "local",
20         "national",
21         "international",
22         NULL
23 };
24
25 char *ext_yesno[] = {
26         "no",
27         "yes",
28         NULL
29 };
30
31
32 /* read extension
33  *
34  * reads extension from given extension number and fills structure
35  */
36 int read_extension(struct extension *ext, char *num)
37 {
38         FILE *fp=NULL;
39         char number[32];
40         char filename[256];
41         char *p;
42         char option[32];
43         char param[256],param2[256];
44         unsigned int line,i;
45         char buffer[1024];
46         int last_in_count = 0, last_out_count = 0;
47
48         /* save number, so &ext and ext.number can be given as parameters - without overwriting itself */
49         SCPY(number, num);
50         
51         if (number[0] == '\0')
52                 return(0);
53
54         SPRINT(filename, "%s/%s/%s/settings", INSTALL_DATA, options.extensions_dir, number);
55
56         if (!(fp = fopen(filename, "r")))
57         {
58                 PDEBUG(DEBUG_CONFIG, "the given extension doesn't exist: \"%s\"\n", filename);
59                 return(0);
60         }
61
62         /* default values */
63         memset(ext, 0, sizeof(struct extension));
64         SCPY(ext->number, number);
65         ext->rights = 4; /* international */
66         ext->tout_setup = 120;
67         ext->tout_dialing = 120;
68         ext->tout_proceeding = 120;
69         ext->tout_alerting = 120;
70         ext->tout_disconnect = 120;
71 //      ext->tout_hold = 900;
72 //      ext->tout_park = 900;
73         ext->cfnr_delay = 20;
74         ext->vbox_codec = CODEC_MONO;
75
76         line=0;
77         while((fgets(buffer, sizeof(buffer), fp)))
78         {
79                 line++;
80                 buffer[sizeof(buffer)-1] = '\0';
81                 if (buffer[0]) buffer[strlen(buffer)-1] = '\0';
82                 p = buffer;
83
84                 while(*p <= 32) /* skip spaces */
85                 {
86                         if (*p == 0)
87                                 break;
88                         p++;
89                 }
90                 if (*p==0 || *p=='#') /* ignore comments and empty line */
91                         continue;
92
93                 option[0]=0;
94                 i=0; /* read option */
95                 while(*p > 32)
96                 {
97                         if (i+1 >= sizeof(option))
98                         {
99                                 PERROR_RUNTIME("Error in %s (line %d): option too long.\n",filename,line);
100                                 break;
101                         }
102                         option[i+1] = '\0';
103                         option[i++] = *p++;
104                 }
105
106                 while(*p <= 32) /* skip spaces */
107                 {
108                         if (*p == 0)
109                                 break;
110                         p++;
111                 }
112
113                 param[0]=0;
114                 param2[0]=0;
115                 if (*p!=0 && *p!='#') /* param */
116                 {
117                         i=0; /* read param */
118                         while(*p > 32)
119                         {
120                                 if (i+1 >= sizeof(param))
121                                 {
122                                         PERROR_RUNTIME("Error in %s (line %d): param too long.\n",filename,line);
123                                         break;
124                                 }
125                                 param[i+1] = '\0';
126                                 param[i++] = *p++;
127                         }
128
129                         while(*p <= 32) /* skip spaces */
130                         {
131                                 if (*p == 0)
132                                         break;
133                                 p++;
134                         }
135
136                         if (*p!=0 && *p!='#') /* param2 */
137                         {
138                                 i=0; /* read param2 */
139                                 while(*p >= 32)
140                                 {
141                                         if (i+1 >= sizeof(param2))
142                                         {
143                                                 PERROR_RUNTIME("Error in %s (line %d): param too long.\n",filename,line);
144                                                 break;
145                                         }
146                                         param2[i+1] = '\0';
147                                         param2[i++] = *p++;
148                                 }
149                         }
150                 }
151
152                 /* at this point we have option and param */
153
154                 /* check option */
155                 if (!strcmp(option,"name"))
156                 {
157                         SCPY(ext->name, param);
158                         if (param2[0])
159                         {
160                                 SCAT(ext->name, " ");
161                                 SCAT(ext->name, param2);
162                         }
163
164                         PDEBUG(DEBUG_CONFIG, "name of extension: %s\n",param);
165                 } else
166                 if (!strcmp(option,"prefix"))
167                 {
168                         SCPY(ext->prefix, param);
169
170                         PDEBUG(DEBUG_CONFIG, "dial prefix on pickup: %s\n",param);
171                 } else
172                 if (!strcmp(option,"next"))
173                 {
174                         SCPY(ext->next, param);
175
176                         PDEBUG(DEBUG_CONFIG, "dial next on pickup: %s\n",param);
177                 } else
178                 if (!strcmp(option,"alarm"))
179                 {
180                         SCPY(ext->alarm, param);
181
182                         PDEBUG(DEBUG_CONFIG, "alarm message (if prefix): %s\n",param);
183                 } else
184                 if (!strcmp(option,"cfu"))
185                 {
186                         SCPY(ext->cfu, param);
187
188                         PDEBUG(DEBUG_CONFIG, "call forward unconditional: %s\n",param);
189                 } else
190                 if (!strcmp(option,"cfb"))
191                 {
192                         SCPY(ext->cfb, param);
193
194                         PDEBUG(DEBUG_CONFIG, "call forward when busy: %s\n",param);
195                 } else
196                 if (!strcmp(option,"cfnr"))
197                 {
198                         SCPY(ext->cfnr, param);
199
200                         PDEBUG(DEBUG_CONFIG, "call forward on no response: %s\n",param);
201                 } else
202                 if (!strcmp(option,"cfnr_delay"))
203                 {
204                         ext->cfnr_delay = atoi(param);
205                         if (ext->cfnr_delay < 0)
206                                 ext->cfnr_delay = 1;
207
208                         PDEBUG(DEBUG_CONFIG, "call forward no response delay: %d\n",ext->cfnr_delay);
209                 } else
210                 if (!strcmp(option,"cfp"))
211                 {
212                         SCPY(ext->cfp, param);
213
214                         PDEBUG(DEBUG_CONFIG, "call forward parallel: %s\n",param);
215                 } else
216                 if (!strcmp(option,"change_forward"))
217                 {
218                         i=0;
219                         while(ext_yesno[i])
220                         {
221                                 if (!strcasecmp(param,ext_yesno[i]))
222                                         break;
223                                 i++;
224                         }
225                         if (ext_yesno[i])
226                         {
227                                 ext->change_forward = i;
228                                 PDEBUG(DEBUG_CONFIG, "allow the change of forwarding: %s\n", ext_yesno[i]);
229                         } else
230                         {
231                                 PDEBUG(DEBUG_CONFIG, "unknown parameter for change_forward: %s\n", param);
232                         }
233                 } else
234                 if (!strcmp(option,"interfaces"))
235                 {
236                         SCPY(ext->interfaces, param);
237
238                         PDEBUG(DEBUG_CONFIG, "interfaces to ring calls to extension: %s %s\n",param,param2);
239                 } else
240                 if (!strcmp(option,"callerid"))
241                 {
242                         ext->callerid_present = INFO_PRESENT_ALLOWED;
243                         if (!strncasecmp(param2, "anonymous", 9))
244                                 ext->callerid_present = INFO_PRESENT_RESTRICTED;
245                         if (!strncasecmp(param, "non", 3))
246                         {
247                                 ext->callerid[0] = '\0';
248                                 ext->callerid_present = INFO_PRESENT_NOTAVAIL;
249                                 ext->callerid_type = INFO_NTYPE_UNKNOWN;
250                                 PDEBUG(DEBUG_CONFIG, "caller id: ID NOT AVAILABLE\n");
251                         } else
252                         switch(param[0])
253                         {
254                                 case 'i':
255                                 case 'I':
256                                 ext->callerid_type = INFO_NTYPE_INTERNATIONAL;
257                                 SCPY(ext->callerid, param+1);
258                                 PDEBUG(DEBUG_CONFIG, "caller id: %s INTERNATIONAL\n",param+1);
259                                 break;
260                                 case 'n':
261                                 case 'N':
262                                 ext->callerid_type = INFO_NTYPE_NATIONAL;
263                                 SCPY(ext->callerid, param+1);
264                                 PDEBUG(DEBUG_CONFIG, "caller id: %s NATIONAL\n",param+1);
265                                 break;
266                                 case 's':
267                                 case 'S':
268                                 ext->callerid_type = INFO_NTYPE_SUBSCRIBER;
269                                 SCPY(ext->callerid, param+1);
270                                 PDEBUG(DEBUG_CONFIG, "caller id: %s SUBSCRIBER\n",param+1);
271                                 break;
272                                 default:
273                                 ext->callerid_type = INFO_NTYPE_UNKNOWN;
274                                 SCPY(ext->callerid, param);
275                                 PDEBUG(DEBUG_CONFIG, "caller id: %s UNKNOWN\n",param);
276                         }
277                         ext->callerid[sizeof(ext->callerid)-1] = 0;
278                 } else
279                 if (!strcmp(option,"id_next_call"))
280                 {
281                         ext->id_next_call_present = INFO_PRESENT_ALLOWED;
282                         if (!strncasecmp(param2, "anonymous", 9))
283                                 ext->id_next_call_present = INFO_PRESENT_RESTRICTED;
284                         if (param[0] == '\0')
285                         {
286                                 ext->id_next_call_present = -1;
287                                 PDEBUG(DEBUG_CONFIG, "id next call: no id for next call\n");
288                         } else
289                         if (!strncasecmp(param, "none", 3))
290                         {
291                                 ext->id_next_call[0] = '\0';
292                                 ext->id_next_call_present = INFO_PRESENT_NOTAVAIL;
293                                 ext->id_next_call_type = INFO_NTYPE_UNKNOWN;
294                                 PDEBUG(DEBUG_CONFIG, "id next call: ID NOT AVAILABLE\n");
295                         } else
296                         switch(param[0])
297                         {
298                                 case 'i':
299                                 case 'I':
300                                 ext->id_next_call_type = INFO_NTYPE_INTERNATIONAL;
301                                 SCPY(ext->id_next_call, param+1);
302                                 PDEBUG(DEBUG_CONFIG, "id next call: %s INTERNATIONAL\n",param+1);
303                                 break;
304                                 case 'n':
305                                 case 'N':
306                                 ext->id_next_call_type = INFO_NTYPE_NATIONAL;
307                                 SCPY(ext->id_next_call, param+1);
308                                 PDEBUG(DEBUG_CONFIG, "id next call: %s NATIONAL\n",param+1);
309                                 break;
310                                 case 's':
311                                 case 'S':
312                                 ext->id_next_call_type = INFO_NTYPE_SUBSCRIBER;
313                                 SCPY(ext->id_next_call, param+1);
314                                 PDEBUG(DEBUG_CONFIG, "id next call: %s SUBSCRIBER\n",param+1);
315                                 break;
316                                 default:
317                                 ext->id_next_call_type = INFO_NTYPE_UNKNOWN;
318                                 SCPY(ext->id_next_call, param);
319                                 PDEBUG(DEBUG_CONFIG, "id next call: %s UNKNOWN\n",param);
320                         }
321
322
323
324                 } else
325                 if (!strcmp(option,"change_callerid"))
326                 {
327                         i=0;
328                         while(ext_yesno[i])
329                         {
330                                 if (!strcasecmp(param,ext_yesno[i]))
331                                         break;
332                                 i++;
333                         }
334                         if (ext_yesno[i])
335                         {
336                                 ext->change_callerid = i;
337                                 PDEBUG(DEBUG_CONFIG, "allow the change of caller id: %s\n", ext_yesno[i]);
338                         } else
339                         {
340                                 PDEBUG(DEBUG_CONFIG, "unknown parameter for change_callerid: %s\n", param);
341                         }
342                 } else
343                 if (!strcmp(option,"anon-ignore"))
344                 {
345                         i=0;
346                         while(ext_yesno[i])
347                         {
348                                 if (!strcasecmp(param,ext_yesno[i]))
349                                         break;
350                                 i++;
351                         }
352                         if (ext_yesno[i])
353                         {
354                                 ext->anon_ignore = i;
355                                 PDEBUG(DEBUG_CONFIG, "ignore restriction of CLIP & COLP %s\n", ext_yesno[i]);
356                         } else
357                         {
358                                 PDEBUG(DEBUG_CONFIG, "unknown parameter given anon-ignore: %s\n", param);
359                         }
360                 } else
361                 if (!strcmp(option,"clip"))
362                 {
363                         if (!strcasecmp(param, "hide"))
364                                 ext->clip = CLIP_HIDE;
365                         else
366                                 ext->clip = CLIP_ASIS;
367
368                         PDEBUG(DEBUG_CONFIG, "clip: %d\n",ext->clip);
369                 } else
370                 if (!strcmp(option,"colp"))
371                 {
372                         if (!strcasecmp(param, "hide"))
373                                 ext->colp = COLP_HIDE;
374                         else if (!strcasecmp(param, "force"))
375                                 ext->colp = COLP_FORCE;
376                         else
377                                 ext->colp = COLP_ASIS;
378
379                         PDEBUG(DEBUG_CONFIG, "colp: %d\n",ext->colp);
380                 } else
381                 if (!strcmp(option,"clip_prefix"))
382                 {
383                         SCPY(ext->clip_prefix, param);
384
385                         PDEBUG(DEBUG_CONFIG, "clip prefix: %s\n",param);
386                 } else
387                 if (!strcmp(option,"keypad"))
388                 {
389                         i=0;
390                         while(ext_yesno[i])
391                         {
392                                 if (!strcasecmp(param,ext_yesno[i]))
393                                         break;
394                                 i++;
395                         }
396                         if (ext_yesno[i])
397                         {
398                                 ext->keypad = i;
399                                 PDEBUG(DEBUG_CONFIG, "use keypad to do call control %s\n", ext_yesno[i]);
400                         } else
401                         {
402                                 PDEBUG(DEBUG_CONFIG, "unknown parameter given keypad: %s\n", param);
403                         }
404                 } else
405                 if (!strcmp(option,"centrex"))
406                 {
407                         i=0;
408                         while(ext_yesno[i])
409                         {
410                                 if (!strcasecmp(param,ext_yesno[i]))
411                                         break;
412                                 i++;
413                         }
414                         if (ext_yesno[i])
415                         {
416                                 ext->centrex = i;
417                                 PDEBUG(DEBUG_CONFIG, "use centrex to display name %s\n", ext_yesno[i]);
418                         } else
419                         {
420                                 PDEBUG(DEBUG_CONFIG, "unknown parameter given centrex: %s\n", param);
421                         }
422                 } else
423                 if (!strcmp(option,"rights"))
424                 {
425                         i=0;
426                         while(ext_rights[i])
427                         {
428                                 if (!strcasecmp(param,ext_rights[i]))
429                                         break;
430                                 i++;
431                         }
432                         if (ext_rights[i])
433                         {
434                                 ext->rights = i;
435                                 PDEBUG(DEBUG_CONFIG, "rights to dial: %s\n", ext_rights[i]);
436                         } else
437                         {
438                                 PDEBUG(DEBUG_CONFIG, "given rights unknown: %s\n", param);
439                         }
440                 } else
441                 if (!strcmp(option,"delete_ext"))
442                 {
443                         i=0;
444                         while(ext_yesno[i])
445                         {
446                                 if (!strcasecmp(param,ext_yesno[i]))
447                                         break;
448                                 i++;
449                         }
450                         if (ext_yesno[i])
451                         {
452                                 ext->delete_ext = i;
453                                 PDEBUG(DEBUG_CONFIG, "enables the delete key function for external calls: %s\n", ext_yesno[i]);
454                         } else
455                         {
456                                 PDEBUG(DEBUG_CONFIG, "unknown parameter given delete: %s\n", param);
457                         }
458                 } else
459                 if (!strcmp(option,"noknocking"))
460                 {
461                         i=0;
462                         while(ext_yesno[i])
463                         {
464                                 if (!strcasecmp(param,ext_yesno[i]))
465                                         break;
466                                 i++;
467                         }
468                         if (ext_yesno[i])
469                         {
470                                 ext->noknocking = i;
471                                 PDEBUG(DEBUG_CONFIG, "noknocking %s\n", ext_yesno[i]);
472                         } else
473                         {
474                                 PDEBUG(DEBUG_CONFIG, "given noknocking param unknown: %s\n", param);
475                         }
476                 } else
477                 if (!strcmp(option,"rxvol"))
478                 {
479                         ext->rxvol = atoi(param);
480                         if (ext->rxvol<-8 || ext->rxvol>8)
481                                 ext->rxvol = 0;
482
483                         PDEBUG(DEBUG_CONFIG, "receive volume: %d\n",ext->rxvol);
484                 } else
485                 if (!strcmp(option,"txvol"))
486                 {
487                         ext->txvol = atoi(param);
488                         if (ext->txvol<-8 || ext->txvol>8)
489                                 ext->txvol = 0;
490
491                         PDEBUG(DEBUG_CONFIG, "transmit volume: %d\n",ext->txvol);
492                 } else
493                 if (!strcmp(option,"tout_setup"))
494                 {
495                         ext->tout_setup = atoi(param);
496                         if (ext->tout_setup < 0)
497                                 ext->tout_setup = 0;
498
499                         PDEBUG(DEBUG_CONFIG, "timeout setup: %d\n",ext->tout_setup);
500                 } else
501                 if (!strcmp(option,"tout_dialing"))
502                 {
503                         ext->tout_dialing = atoi(param);
504                         if (ext->tout_dialing < 0)
505                                 ext->tout_dialing = 0;
506
507                         PDEBUG(DEBUG_CONFIG, "timeout dialing: %d\n",ext->tout_dialing);
508                 } else
509                 if (!strcmp(option,"tout_proceeding"))
510                 {
511                         ext->tout_proceeding = atoi(param);
512                         if (ext->tout_proceeding < 0)
513                                 ext->tout_proceeding = 0;
514
515                         PDEBUG(DEBUG_CONFIG, "timeout proceeding: %d\n",ext->tout_proceeding);
516                 } else
517                 if (!strcmp(option,"tout_alerting"))
518                 {
519                         ext->tout_alerting = atoi(param);
520                         if (ext->tout_alerting < 0)
521                                 ext->tout_alerting = 0;
522
523                         PDEBUG(DEBUG_CONFIG, "timeout alerting: %d\n",ext->tout_alerting);
524                 } else
525                 if (!strcmp(option,"tout_disconnect"))
526                 {
527                         ext->tout_disconnect = atoi(param);
528                         if (ext->tout_disconnect < 0)
529                                 ext->tout_disconnect = 0;
530
531                         PDEBUG(DEBUG_CONFIG, "timeout disconnect: %d\n",ext->tout_disconnect);
532                 } else
533 #if 0
534                 if (!strcmp(option,"tout_hold"))
535                 {
536                         ext->tout_hold = atoi(param);
537                         if (ext->tout_hold < 0)
538                                 ext->tout_hold = 0;
539
540                         PDEBUG(DEBUG_CONFIG, "timeout hold: %d\n",ext->tout_hold);
541                 } else
542                 if (!strcmp(option,"tout_park"))
543                 {
544                         ext->tout_park = atoi(param);
545                         if (ext->tout_park < 0)
546                                 ext->tout_park = 0;
547
548                         PDEBUG(DEBUG_CONFIG, "timeout park: %d\n",ext->tout_park);
549                 } else
550 #endif
551                 if (!strcmp(option,"own_setup"))
552                 {
553                         i=0;
554                         while(ext_yesno[i])
555                         {
556                                 if (!strcasecmp(param,ext_yesno[i]))
557                                         break;
558                                 i++;
559                         }
560                         if (ext_yesno[i])
561                         {
562                                 ext->own_setup = i;
563                                 PDEBUG(DEBUG_CONFIG, "own_setup %s\n", ext_yesno[i]);
564                         } else
565                         {
566                                 PDEBUG(DEBUG_CONFIG, "given own_setup param unknown: %s\n", param);
567                         }
568                 } else
569                 if (!strcmp(option,"own_proceeding"))
570                 {
571                         i=0;
572                         while(ext_yesno[i])
573                         {
574                                 if (!strcasecmp(param,ext_yesno[i]))
575                                         break;
576                                 i++;
577                         }
578                         if (ext_yesno[i])
579                         {
580                                 ext->own_proceeding = i;
581                                 PDEBUG(DEBUG_CONFIG, "own_proceeding %s\n", ext_yesno[i]);
582                         } else
583                         {
584                                 PDEBUG(DEBUG_CONFIG, "given own_proceeding param unknown: %s\n", param);
585                         }
586                 } else
587                 if (!strcmp(option,"own_alerting"))
588                 {
589                         i=0;
590                         while(ext_yesno[i])
591                         {
592                                 if (!strcasecmp(param,ext_yesno[i]))
593                                         break;
594                                 i++;
595                         }
596                         if (ext_yesno[i])
597                         {
598                                 ext->own_alerting = i;
599                                 PDEBUG(DEBUG_CONFIG, "own_alerting %s\n", ext_yesno[i]);
600                         } else
601                         {
602                                 PDEBUG(DEBUG_CONFIG, "given own_alerting param unknown: %s\n", param);
603                         }
604                 } else
605                 if (!strcmp(option,"own_cause"))
606                 {
607                         i=0;
608                         while(ext_yesno[i])
609                         {
610                                 if (!strcasecmp(param,ext_yesno[i]))
611                                         break;
612                                 i++;
613                         }
614                         if (ext_yesno[i])
615                         {
616                                 ext->own_cause = i;
617                                 PDEBUG(DEBUG_CONFIG, "own_cause %s\n", ext_yesno[i]);
618                         } else
619                         {
620                                 PDEBUG(DEBUG_CONFIG, "given own_cause param unknown: %s\n", param);
621                         }
622                 } else
623                 if (!strcmp(option,"facility"))
624                 {
625                         i=0;
626                         while(ext_yesno[i])
627                         {
628                                 if (!strcasecmp(param,ext_yesno[i]))
629                                         break;
630                                 i++;
631                         }
632                         if (ext_yesno[i])
633                         {
634                                 ext->facility = i;
635                                 PDEBUG(DEBUG_CONFIG, "facility %s\n", ext_yesno[i]);
636                         } else
637                         {
638                                 PDEBUG(DEBUG_CONFIG, "given facility param unknown: %s\n", param);
639                         }
640                 } else
641                 if (!strcmp(option,"display_cause"))
642                 {
643                         if (!strcasecmp(param, "german"))
644                                 ext->display_cause = DISPLAY_CAUSE_GERMAN;
645                         else if (!strcasecmp(param, "english"))
646                                 ext->display_cause = DISPLAY_CAUSE_ENGLISH;
647                         else if (!strcasecmp(param, "german-location"))
648                                 ext->display_cause = DISPLAY_LOCATION_GERMAN;
649                         else if (!strcasecmp(param, "english-location"))
650                                 ext->display_cause = DISPLAY_LOCATION_ENGLISH;
651                         else if (!strcasecmp(param, "number"))
652                                 ext->display_cause = DISPLAY_CAUSE_NUMBER;
653                         else
654                                 ext->display_cause = DISPLAY_CAUSE_NONE;
655
656                         PDEBUG(DEBUG_CONFIG, "display cause: %d\n",ext->display_cause);
657                 } else
658 #if 0
659                 if (!strcmp(option,"display_ext"))
660                 {
661                         if (!strcasecmp(param, "number"))
662                                 ext->display_ext = DISPLAY_CID_NUMBER;
663                         else if (!strcasecmp(param, "abbrev"))
664                                 ext->display_ext = DISPLAY_CID_ABBREVIATION;
665                         else if (!strcasecmp(param, "name"))
666                                 ext->display_ext = DISPLAY_CID_NAME;
667                         else if (!strcasecmp(param, "number-name"))
668                                 ext->display_ext = DISPLAY_CID_NUMBER_NAME;
669                         else if (!strcasecmp(param, "name-number"))
670                                 ext->display_ext = DISPLAY_CID_NAME_NUMBER;
671                         else if (!strcasecmp(param, "abbrev-number"))
672                                 ext->display_ext = DISPLAY_CID_ABBREV_NUMBER;
673                         else if (!strcasecmp(param, "abbrev-name"))
674                                 ext->display_ext = DISPLAY_CID_ABBREV_NAME;
675                         else if (!strcasecmp(param, "abbrev-name-number"))
676                                 ext->display_ext = DISPLAY_CID_ABBREV_NAME_NUMBER;
677                         else if (!strcasecmp(param, "abbrev-number-name"))
678                                 ext->display_ext = DISPLAY_CID_ABBREV_NUMBER_NAME;
679                         else
680                                 ext->display_ext = DISPLAY_CID_ASIS;
681
682                         PDEBUG(DEBUG_CONFIG, "display ext: %d\n",ext->display_ext);
683                 } else
684 #endif
685                 if (!strcmp(option,"display_ext"))
686                 {
687                         i=0;
688                         while(ext_yesno[i])
689                         {
690                                 if (!strcasecmp(param,ext_yesno[i]))
691                                         break;
692                                 i++;
693                         }
694                         if (ext_yesno[i])
695                         {
696                                 ext->display_ext = i;
697                                 PDEBUG(DEBUG_CONFIG, "display ext %s\n", ext_yesno[i]);
698                         } else
699                         {
700                                 PDEBUG(DEBUG_CONFIG, "given display_ext param unknown: %s\n", param);
701                         }
702                 } else
703                 if (!strcmp(option,"display_int"))
704                 {
705                         i=0;
706                         while(ext_yesno[i])
707                         {
708                                 if (!strcasecmp(param,ext_yesno[i]))
709                                         break;
710                                 i++;
711                         }
712                         if (ext_yesno[i])
713                         {
714                                 ext->display_int = i;
715                                 PDEBUG(DEBUG_CONFIG, "display int %s\n", ext_yesno[i]);
716                         } else
717                         {
718                                 PDEBUG(DEBUG_CONFIG, "given display_int param unknown: %s\n", param);
719                         }
720                 } else
721                 if (!strcmp(option,"display_fake"))
722                 {
723                         i=0;
724                         while(ext_yesno[i])
725                         {
726                                 if (!strcasecmp(param,ext_yesno[i]))
727                                         break;
728                                 i++;
729                         }
730                         if (ext_yesno[i])
731                         {
732                                 ext->display_fake = i;
733                                 PDEBUG(DEBUG_CONFIG, "display fake caller ids %s\n", ext_yesno[i]);
734                         } else
735                         {
736                                 PDEBUG(DEBUG_CONFIG, "given display_fake param unknown: %s\n", param);
737                         }
738                 } else
739                 if (!strcmp(option,"display_anon"))
740                 {
741                         i=0;
742                         while(ext_yesno[i])
743                         {
744                                 if (!strcasecmp(param,ext_yesno[i]))
745                                         break;
746                                 i++;
747                         }
748                         if (ext_yesno[i])
749                         {
750                                 ext->display_anon = i;
751                                 PDEBUG(DEBUG_CONFIG, "display anonymouse ids %s\n", ext_yesno[i]);
752                         } else
753                         {
754                                 PDEBUG(DEBUG_CONFIG, "given display_anon param unknown: %s\n", param);
755                         }
756                 } else
757                 if (!strcmp(option,"display_menu"))
758                 {
759                         i=0;
760                         while(ext_yesno[i])
761                         {
762                                 if (!strcasecmp(param,ext_yesno[i]))
763                                         break;
764                                 i++;
765                         }
766                         if (ext_yesno[i])
767                         {
768                                 ext->display_menu = i;
769                                 PDEBUG(DEBUG_CONFIG, "display menu %s\n", ext_yesno[i]);
770                         } else
771                         {
772                                 PDEBUG(DEBUG_CONFIG, "given display_menu param unknown: %s\n", param);
773                         }
774                 } else
775                 if (!strcmp(option,"display_dialing"))
776                 {
777                         i=0;
778                         while(ext_yesno[i])
779                         {
780                                 if (!strcasecmp(param,ext_yesno[i]))
781                                         break;
782                                 i++;
783                         }
784                         if (ext_yesno[i])
785                         {
786                                 ext->display_dialing = i;
787                                 PDEBUG(DEBUG_CONFIG, "display dialing %s\n", ext_yesno[i]);
788                         } else
789                         {
790                                 PDEBUG(DEBUG_CONFIG, "given display_dialing param unknown: %s\n", param);
791                         }
792                 } else
793                 if (!strcmp(option,"display_name"))
794                 {
795                         i=0;
796                         while(ext_yesno[i])
797                         {
798                                 if (!strcasecmp(param,ext_yesno[i]))
799                                         break;
800                                 i++;
801                         }
802                         if (ext_yesno[i])
803                         {
804                                 ext->display_name = i;
805                                 PDEBUG(DEBUG_CONFIG, "display name %s\n", ext_yesno[i]);
806                         } else
807                         {
808                                 PDEBUG(DEBUG_CONFIG, "given display_name param unknown: %s\n", param);
809                         }
810                 } else
811                 if (!strcmp(option,"tones_dir"))
812                 {
813                         if (param[strlen(param)-1] == '/')
814                                 param[strlen(param)-1]=0;
815                         SCPY(ext->tones_dir, param);
816
817                         PDEBUG(DEBUG_CONFIG, "directory of tones: %s\n",param);
818                 } else
819                 if (!strcmp(option,"record"))
820                 {
821                         if (!strcasecmp(param, "mono"))
822                                 ext->record = CODEC_MONO;
823                         else if (!strcasecmp(param, "stereo"))
824                                 ext->record = CODEC_STEREO;
825                         else if (!strcasecmp(param, "8bit"))
826                                 ext->record = CODEC_8BIT;
827                         else if (!strcasecmp(param, "law"))
828                                 ext->record = CODEC_LAW;
829                         else
830                                 ext->record = CODEC_OFF;
831                         PDEBUG(DEBUG_CONFIG, "given record param: %s\n", param);
832                 } else
833                 if (!strcmp(option,"password"))
834                 {
835                         SCPY(ext->password, param);
836
837                         PDEBUG(DEBUG_CONFIG, "password: %s\n",param);
838                 } else
839                 if (!strcmp(option,"vbox_mode"))
840                 {
841                         if (!strcasecmp(param, "parallel"))
842                                 ext->vbox_mode = VBOX_MODE_PARALLEL;
843                         else if (!strcasecmp(param, "announcement"))
844                                 ext->vbox_mode = VBOX_MODE_ANNOUNCEMENT;
845                         else
846                                 ext->vbox_mode = VBOX_MODE_NORMAL;
847                         PDEBUG(DEBUG_CONFIG, "given vbox mode: %s\n", param);
848                 } else
849                 if (!strcmp(option,"vbox_codec"))
850                 {
851                         if (!strcasecmp(param, "stereo"))
852                                 ext->vbox_codec = CODEC_STEREO;
853                         else if (!strcasecmp(param, "8bit"))
854                                 ext->vbox_codec = CODEC_8BIT;
855                         else if (!strcasecmp(param, "law"))
856                                 ext->vbox_codec = CODEC_LAW;
857                         else
858                                 ext->vbox_codec = CODEC_MONO;
859                         PDEBUG(DEBUG_CONFIG, "given record param: %s\n", param);
860                 } else
861                 if (!strcmp(option,"vbox_time"))
862                 {
863                         ext->vbox_time = atoi(param);
864                         if (ext->vbox_time < 0)
865                                 ext->vbox_time = 0;
866
867                         PDEBUG(DEBUG_CONFIG, "vbox time to record: %d\n",ext->vbox_time);
868                 } else
869                 if (!strcmp(option,"vbox_display"))
870                 {
871                         if (!strcasecmp(param, "detailed")
872                          || !strcasecmp(param, "detailled"))
873                                 ext->vbox_display = VBOX_DISPLAY_DETAILED;
874                         else if (!strcasecmp(param, "off"))
875                                 ext->vbox_display = VBOX_DISPLAY_OFF;
876                         else
877                                 ext->vbox_display = VBOX_DISPLAY_BRIEF;
878                         PDEBUG(DEBUG_CONFIG, "given vbox mode: %s\n", param);
879                 } else
880                 if (!strcmp(option,"vbox_language"))
881                 {
882                         if (!strcasecmp(param, "german"))
883                                 ext->vbox_language = VBOX_LANGUAGE_GERMAN;
884                         else
885                                 ext->vbox_language = VBOX_LANGUAGE_ENGLISH;
886                         PDEBUG(DEBUG_CONFIG, "given vbox mode: %s\n", param);
887                 } else
888                 if (!strcmp(option,"vbox_email"))
889                 {
890                         SCPY(ext->vbox_email, param);
891                         PDEBUG(DEBUG_CONFIG, "given vbox email: %s\n", param);
892                 } else
893                 if (!strcmp(option,"vbox_email_file"))
894                 {
895                         i=0;
896                         while(ext_yesno[i])
897                         {
898                                 if (!strcasecmp(param,ext_yesno[i]))
899                                         break;
900                                 i++;
901                         }
902                         if (ext_yesno[i])
903                         {
904                                 ext->vbox_email_file = i;
905                                 PDEBUG(DEBUG_CONFIG, "attach audio file %s\n", ext_yesno[i]);
906                         } else
907                         {
908                                 PDEBUG(DEBUG_CONFIG, "given vbox_email_file param unknown: %s\n", param);
909                         }
910                 } else
911                 if (!strcmp(option,"vbox_free"))
912                 {
913                         i=0;
914                         while(ext_yesno[i])
915                         {
916                                 if (!strcasecmp(param,ext_yesno[i]))
917                                         break;
918                                 i++;
919                         }
920                         if (ext_yesno[i])
921                         {
922                                 ext->vbox_free = i;
923                                 PDEBUG(DEBUG_CONFIG, "vbox_free %s\n", ext_yesno[i]);
924                         } else
925                         {
926                                 PDEBUG(DEBUG_CONFIG, "given vbox_free param unknown: %s\n", param);
927                         }
928                 } else
929                 if (!strcmp(option,"last_in"))
930                 {
931                         if (param[0] && last_in_count<MAX_REMEMBER)
932                         {
933                                 SCPY(ext->last_in[last_in_count], param);
934                                 last_in_count++;
935                         }
936                         PDEBUG(DEBUG_CONFIG, "last_in dialed number: %s\n",param);
937                 } else
938                 if (!strcmp(option,"last_out"))
939                 {
940                         if (param[0] && last_out_count<MAX_REMEMBER)
941                         {
942                                 SCPY(ext->last_out[last_out_count], param);
943                                 last_out_count++;
944                         }
945                         PDEBUG(DEBUG_CONFIG, "last_out dialed number: %s\n",param);
946                 } else
947                 if (!strcmp(option,"datacall"))
948                 {
949                         i=0;
950                         while(ext_yesno[i])
951                         {
952                                 if (!strcasecmp(param,ext_yesno[i]))
953                                         break;
954                                 i++;
955                         }
956                         if (ext_yesno[i])
957                         {
958                                 ext->datacall = i;
959                                 PDEBUG(DEBUG_CONFIG, "datacall %s\n", ext_yesno[i]);
960                         } else
961                         {
962                                 PDEBUG(DEBUG_CONFIG, "given datacall param unknown: %s\n", param);
963                         }
964                 } else
965                 if (!strcmp(option,"seconds"))
966                 {
967                         i=0;
968                         while(ext_yesno[i])
969                         {
970                                 if (!strcasecmp(param,ext_yesno[i]))
971                                         break;
972                                 i++;
973                         }
974                         if (ext_yesno[i])
975                         {
976                                 ext->no_seconds = 1-i;
977                                 PDEBUG(DEBUG_CONFIG, "seconds %s\n", ext_yesno[i]);
978                         } else
979                         {
980                                 PDEBUG(DEBUG_CONFIG, "unknown param for seconds: %s\n", param);
981                         }
982                 } else
983                 {
984                         PERROR_RUNTIME("Error in %s (line %d): wrong option keyword %s.\n",filename,line,option);
985                 }
986         }
987
988         if (fp) fclose(fp);
989         return(1);
990 }
991
992
993 /* write extension
994  *
995  * writes extension for given extension number from structure
996  */
997 int write_extension(struct extension *ext, char *number)
998 {
999         FILE *fp=NULL;
1000         char filename[256];
1001         int i;
1002
1003         if (number[0] == '\0')
1004                 return(0);
1005
1006         SPRINT(filename, "%s/%s/%s/settings", INSTALL_DATA, options.extensions_dir, number);
1007
1008         if (!(fp = fopen(filename, "w")))
1009         {
1010                 PERROR("Cannot open settings: \"%s\"\n", filename);
1011                 return(0);
1012         }
1013
1014         fprintf(fp,"# Settings of extension %s\n\n", number);
1015
1016         fprintf(fp,"# Name of extension:\n");
1017         fprintf(fp,"name            %s\n\n",ext->name);
1018
1019         fprintf(fp,"# Predialed prefix after pick-up of the phone\n");
1020         fprintf(fp,"prefix          %s\n\n",ext->prefix);
1021
1022         fprintf(fp,"# Next prefix to dial pick-up of the phone\n");
1023         fprintf(fp,"# This will be cleared on hangup.\n");
1024         fprintf(fp,"next            %s\n\n",ext->next);
1025
1026 //      fprintf(fp,"# Set up alarm message after prefix is dialed and connection is established\n");
1027 //      fprintf(fp,"alarm           %s\n\n",ext->alarm);
1028
1029         fprintf(fp,"# Interface(s) to ring on calls to extension (as named in interface.conf)\n");
1030         fprintf(fp,"# Seperate multiple interfaces by using komma without spaces\n");
1031         fprintf(fp,"# Example: Int would ring on the interface with the name \"Int\"");
1032         fprintf(fp,"#          Int1,Int2 would ring incoming calls on both interfaces Int1 and Int2.\n");
1033         fprintf(fp,"interfaces      %s\n\n",ext->interfaces);
1034
1035         fprintf(fp,"# Call Forward Unconditional (CFU)\n");
1036         fprintf(fp,"# No port will be called, CFB, CFNR and CFP is ignored.\n");
1037         fprintf(fp,"# Use keyword \"vbox\" to forward call directly to answering machine.\n");
1038         fprintf(fp,"cfu             %s\n\n",ext->cfu);
1039
1040         fprintf(fp,"# Call Forward when Busy (CFB)\n");
1041         fprintf(fp,"# If the extension is in use at least once, this forward is done.\n");
1042         fprintf(fp,"# In case of busy line, CFNR and CFP is ignored.\n");
1043         fprintf(fp,"# Use keyword \"vbox\" to forward call to answering machine when busy.\n");
1044         fprintf(fp,"cfb             %s\n\n",ext->cfb);
1045
1046         fprintf(fp,"# Call Forward on No Response (CFNR)\n");
1047         fprintf(fp,"# If noone answers, the call is forwarded, ports and CFP will be released.\n");
1048         fprintf(fp,"# The default delay is 20 seconds.\n");
1049         fprintf(fp,"# Use keyword \"vbox\" to forward call to answering machine on no response.\n");
1050         fprintf(fp,"cfnr            %s\n",ext->cfnr);
1051         fprintf(fp,"cfnr_delay      %d\n\n",ext->cfnr_delay);
1052
1053         fprintf(fp,"# Call Forward Parallel (CFP)\n");
1054         fprintf(fp,"# Call will ring on the forwarded number, simulaniousely with the ports.\n");
1055         fprintf(fp,"cfp             %s\n\n",ext->cfp);
1056
1057         fprintf(fp,"# Allow user to change call forwarding.\n");
1058         fprintf(fp,"change_forward  %s\n\n", ext_yesno[ext->change_forward]);
1059
1060         fprintf(fp,"# Caller id\n# This must be one of the following:\n");
1061         fprintf(fp,"# <number> (as dialed from your local area)\n");
1062         fprintf(fp,"# <number> anonymous (will only be shown to emergency phones)\n");
1063         fprintf(fp,"# none (no number available at all)\n");
1064         fprintf(fp,"# by default the number is of type UNKNOWN (for MULTIPOINT lines)\n");
1065         fprintf(fp,"# if your caller id is not screened on outgoing calls use one of the following:\n");
1066         fprintf(fp,"# use prefix 'i' for TYPE INTERNATIONAL (i<county code><areacode+number>)\n");
1067         fprintf(fp,"# use prefix 'n' for TYPE NATIONAL (n<areacode+number>)\n");
1068         fprintf(fp,"# use prefix 's' for TYPE SUBSCRIBER (s<local number>)\n");
1069         if (ext->callerid_present == INFO_PRESENT_NOTAVAIL)
1070                 fprintf(fp,"callerid        none\n\n");
1071         else
1072         {
1073                 switch(ext->callerid_type)
1074                 {
1075                         case INFO_NTYPE_INTERNATIONAL:
1076                         fprintf(fp,"callerid        i%s%s\n\n",ext->callerid, (ext->callerid_present==INFO_PRESENT_RESTRICTED)?" anonymous":"");
1077                         break;
1078                         case INFO_NTYPE_NATIONAL:
1079                         fprintf(fp,"callerid        n%s%s\n\n",ext->callerid, (ext->callerid_present==INFO_PRESENT_RESTRICTED)?" anonymous":"");
1080                         break;
1081                         case INFO_NTYPE_SUBSCRIBER:
1082                         fprintf(fp,"callerid        s%s%s\n\n",ext->callerid, (ext->callerid_present==INFO_PRESENT_RESTRICTED)?" anonymous":"");
1083                         break;
1084                         default:
1085                         fprintf(fp,"callerid        %s%s\n\n",ext->callerid, (ext->callerid_present==INFO_PRESENT_RESTRICTED)?" anonymous":"");
1086                 }
1087         }
1088
1089         fprintf(fp,"# Caller id for next call (see caller id)\n");
1090         if (ext->id_next_call_present < 0)
1091                 fprintf(fp,"id_next_call    \n\n");
1092         else if (ext->id_next_call_present == INFO_PRESENT_NOTAVAIL)
1093                 fprintf(fp,"id_next_call    none\n\n");
1094         else
1095         {
1096                 switch(ext->id_next_call_type)
1097                 {
1098                         case INFO_NTYPE_INTERNATIONAL:
1099                         fprintf(fp,"id_next_call    i%s%s\n\n",ext->id_next_call, (ext->id_next_call_present==INFO_PRESENT_RESTRICTED)?" anonymous":"");
1100                         break;
1101                         case INFO_NTYPE_NATIONAL:
1102                         fprintf(fp,"id_next_call    n%s%s\n\n",ext->id_next_call, (ext->id_next_call_present==INFO_PRESENT_RESTRICTED)?" anonymous":"");
1103                         break;
1104                         case INFO_NTYPE_SUBSCRIBER:
1105                         fprintf(fp,"id_next_call    s%s%s\n\n",ext->id_next_call, (ext->id_next_call_present==INFO_PRESENT_RESTRICTED)?" anonymous":"");
1106                         break;
1107                         default:
1108                         fprintf(fp,"id_next_call    %s%s\n\n",ext->id_next_call, (ext->id_next_call_present==INFO_PRESENT_RESTRICTED)?" anonymous":"");
1109                 }
1110         }
1111
1112         fprintf(fp,"# Allow user to change caller ID.\n");
1113         fprintf(fp,"change_callerid %s\n\n", ext_yesno[ext->change_callerid]);
1114
1115         fprintf(fp,"# Caller Line Identification Presentation (CLIP)\n");
1116         fprintf(fp,"# clip (asis|hide)\n");
1117         fprintf(fp,"# asis: On forwarded calls the CLIP is used as presented by the calling party.\n");
1118         fprintf(fp,"# hide: Always use extension's caller id, even on forwared calls.\n");
1119         switch(ext->clip)
1120         {
1121                 case CLIP_HIDE:
1122                 fprintf(fp,"clip            hide\n\n");
1123                 break;
1124                 default:
1125                 fprintf(fp,"clip            asis\n\n");
1126         }
1127
1128         fprintf(fp,"# Connected Line Identification Presentation (COLP)\n");
1129         fprintf(fp,"# colp (asis|hide|force)\n");
1130         fprintf(fp,"# asis: Provides colp as defined by the extension's caller id.\n");
1131         fprintf(fp,"#       On forwarded calls the COLP is used as presented by the called party.\n");
1132         fprintf(fp,"# hide: Always use extension's caller id, even on forwared calls.\n");
1133         fprintf(fp,"# force: If COLP is not presented by forwarded calls the dialed number is used.\n");
1134         switch(ext->colp)
1135         {
1136                 case COLP_HIDE:
1137                 fprintf(fp,"colp            hide\n\n");
1138                 break;
1139                 case COLP_FORCE:
1140                 fprintf(fp,"colp            force\n\n");
1141                 break;
1142                 default:
1143                 fprintf(fp,"colp            asis\n\n");
1144         }
1145
1146         fprintf(fp,"# CLIP Prefix\n");
1147         fprintf(fp,"# Adds a prefix to incomming caller IDs, so telephones will be able to respond\n");
1148         fprintf(fp,"# to unanswered calls from their list. The prefix must be the digit(s) to get\n");
1149         fprintf(fp,"# an external line. The caller ID will then be extendet so that they can be\n");
1150         fprintf(fp,"# dialed from internal telephones. Many telephones have this feature, but some\n");
1151         fprintf(fp,"# don't.\n");
1152         fprintf(fp,"clip_prefix     %s\n\n",ext->clip_prefix);
1153
1154         fprintf(fp,"# Keypad control\n");
1155         fprintf(fp,"# If supported by telephone, pressing a key on the keypad will not result in\n");
1156         fprintf(fp,"# DTMF tone, but the digit is transmitted via D-channel diaing info.\n");
1157         fprintf(fp,"keypad          %s\n\n",(ext->keypad)?"yes":"no");
1158
1159         fprintf(fp,"# Called Name Identification Presentation (CNIP/CONP)\n");
1160         fprintf(fp,"# If supported by telephone, special information element on the d-channel are\n");
1161         fprintf(fp,"# used to show name of caller. It is supported by newer Siemens telephones\n# (Centrex).\n");
1162         fprintf(fp,"centrex         %s  #this is currently not working!!!\n\n",(ext->centrex)?"yes":"no");
1163
1164         fprintf(fp,"# Ignore restriction of COLP and CLIP\n");
1165         fprintf(fp,"# In this case even restricted numbers are presented to this extension.\n");
1166         fprintf(fp,"# This also works for incoming external anonymous calls IF:\n");
1167         fprintf(fp,"# You have the CLIRIGN feature like POLICE or equivalent.\n");
1168         fprintf(fp,"anon-ignore     %s\n\n",(ext->anon_ignore)?"yes":"no");
1169
1170         fprintf(fp,"# Dialing rights (none|internal|local|national|international)\n");
1171         fprintf(fp,"rights          %s\n\n",ext_rights[ext->rights]);
1172
1173         fprintf(fp,"# Delete function for external calls. '*' will delete the last digit, '#' will\n");
1174         fprintf(fp,"# delete the complete number. Also enable 'display_dialing' to see on the\n");
1175         fprintf(fp,"# display what actually happens.\n");
1176         fprintf(fp,"delete_ext      %s\n\n",ext_yesno[ext->delete_ext]);
1177
1178         fprintf(fp,"# If noknocking is enabled, the caller will get a busy message when the\n");
1179         fprintf(fp,"# extension is doing at least one call.\n");
1180         fprintf(fp,"noknocking      %s\n\n",ext_yesno[ext->noknocking]);
1181
1182         fprintf(fp,"# Transmit volume (-8 .. 8)\n");
1183         fprintf(fp,"# 0 = normal\n");
1184         fprintf(fp,"# 1 = double, 2 = quadrupel, 8 = 256 times (amplitude)\n");
1185         fprintf(fp,"# -1 = half, -2 = quarter, 8 = 1/256th (amplitude)\n");
1186         fprintf(fp,"# Audio data is limited to the maximum value when exceeds limit.\n");
1187         fprintf(fp,"txvol           %d\n\n",ext->txvol);
1188
1189         fprintf(fp,"# Receive volume (-8 .. 8)\n");
1190         fprintf(fp,"# (see txvol)\n");
1191         fprintf(fp,"rxvol           %d\n\n",ext->rxvol);
1192
1193         fprintf(fp,"# Timeout values\n# The keywords specify the following timeouts:\n");
1194         fprintf(fp,"# tout_setup: after pickup before dialing anything. (default 60 seconds)\n");
1195         fprintf(fp,"# tout_dialing: after dialing last digit of uncomplete number (default 15)\n");
1196         fprintf(fp,"# tout_proceeding: after start proceeding (default 120)\n");
1197         fprintf(fp,"# tout_alerting: after start ringing (default 120)\n");
1198         fprintf(fp,"# tout_disconnect: after disconnect (default 120)\n");
1199 //      fprintf(fp,"# tout_hold: maximum time to hold a call (default 900)\n");
1200 //      fprintf(fp,"# tout_park: maximum time to park a call (default 900)\n");
1201         fprintf(fp,"# All timeouts may be disabled by using keyword 'off' instead of seconds.\n");
1202         fprintf(fp,"# All timeouts refer to internal ports only. External timeouts are controlled\n");
1203         fprintf(fp,"# by external line.\n");
1204         if (ext->tout_setup)
1205                 fprintf(fp,"tout_setup      %d\n",ext->tout_setup);
1206         else
1207                 fprintf(fp,"tout_setup      off\n");
1208         if (ext->tout_dialing)
1209                 fprintf(fp,"tout_dialing    %d\n",ext->tout_dialing);
1210         else
1211                 fprintf(fp,"tout_dialing    off\n");
1212         if (ext->tout_proceeding)
1213                 fprintf(fp,"tout_proceeding %d\n",ext->tout_proceeding);
1214         else
1215                 fprintf(fp,"tout_proceeding off\n");
1216         if (ext->tout_alerting)
1217                 fprintf(fp,"tout_alerting   %d\n",ext->tout_alerting);
1218         else
1219                 fprintf(fp,"tout_alerting   off\n");
1220         if (ext->tout_disconnect)
1221                 fprintf(fp,"tout_disconnect %d\n\n",ext->tout_disconnect);
1222         else
1223                 fprintf(fp,"tout_disconnect off\n\n");
1224 //      if (ext->tout_hold)
1225 //              fprintf(fp,"tout_hold       %d\n",ext->tout_hold);
1226 //      else
1227 //              fprintf(fp,"tout_hold       off\n");
1228 //      if (ext->tout_park)
1229 //              fprintf(fp,"tout_park       %d\n\n",ext->tout_park);
1230 //      else
1231 //              fprintf(fp,"tout_park       off\n\n");
1232
1233         fprintf(fp,"# Force to use tones and announcements generated by the pbx.\n");
1234         fprintf(fp,"# For internal calls always own tones are used. You may specify own tones for\n");
1235         fprintf(fp,"# different call states:\n");
1236         fprintf(fp,"# own_setup (dialtone and during dialing)\n");
1237         fprintf(fp,"# own_proceeding (call in poceeding state)\n");
1238         fprintf(fp,"# own_alerting (call is ringing)\n");
1239         fprintf(fp,"# own_cause (when the call gets disconnected or failed to be completed)\n");
1240         fprintf(fp,"own_setup       %s\n",ext_yesno[ext->own_setup]);
1241         fprintf(fp,"own_proceeding  %s\n",ext_yesno[ext->own_proceeding]);
1242         fprintf(fp,"own_alerting    %s\n",ext_yesno[ext->own_alerting]);
1243         fprintf(fp,"own_cause       %s\n\n",ext_yesno[ext->own_cause]);
1244
1245         fprintf(fp,"# Allow facility information to be transfered to the telephone.\n");
1246         fprintf(fp,"# This is equired to receive advice of charge.\n");
1247         fprintf(fp,"facility        %s\n\n",ext_yesno[ext->facility]);
1248
1249         fprintf(fp,"# Display clear causes using display messages (Q.850)\n# This must be one of the following:\n");
1250         fprintf(fp,"# none (no displaying of clear causes)\n");
1251         fprintf(fp,"# english (display cause text in english)\n");
1252         fprintf(fp,"# german (display cause text in german)\n");
1253         fprintf(fp,"# number (display cause number only)\n");
1254         fprintf(fp,"# english-location (display cause text in english and location)\n");
1255         fprintf(fp,"# german-location (display cause text in german and location)\n");
1256         switch(ext->display_cause)
1257         {
1258                 case DISPLAY_CAUSE_ENGLISH:
1259                 fprintf(fp,"display_cause   english\n\n");
1260                 break;
1261                 case DISPLAY_CAUSE_GERMAN:
1262                 fprintf(fp,"display_cause   german\n\n");
1263                 break;
1264                 case DISPLAY_LOCATION_ENGLISH:
1265                 fprintf(fp,"display_cause   english-location\n\n");
1266                 break;
1267                 case DISPLAY_LOCATION_GERMAN:
1268                 fprintf(fp,"display_cause   german-location\n\n");
1269                 break;
1270                 case DISPLAY_CAUSE_NUMBER:
1271                 fprintf(fp,"display_cause   number\n\n");
1272                 break;
1273                 default:
1274                 fprintf(fp,"display_cause   none\n\n");
1275         }
1276
1277         fprintf(fp,"# Display external caller ids using display override (yes or no)\n");
1278         fprintf(fp,"# example: \"15551212\"\n");
1279         fprintf(fp,"display_ext     %s\n\n",(ext->display_ext)?"yes":"no");
1280
1281         fprintf(fp,"# Display internal caller ids using display override (yes or no)\n");
1282         fprintf(fp,"# example: \"200 (int)\"\n");
1283         fprintf(fp,"display_int     %s\n\n",(ext->display_int)?"yes":"no");
1284
1285         fprintf(fp,"# Display if calls are anonymous using display override (yes or no)\n");
1286         fprintf(fp,"# This makes only sense if the anon-ignore feature is enabled.\n");
1287         fprintf(fp,"# example: \"15551212 anon\"\n");
1288         fprintf(fp,"display_anon    %s\n\n",(ext->display_anon)?"yes":"no");
1289
1290         fprintf(fp,"# Display fake caller ids using display override (yes or no)\n");
1291         fprintf(fp,"# If the caller uses \"clip no screening\", you will see if the number is\n");
1292         fprintf(fp,"# real or fake\n");
1293         fprintf(fp,"# example: \"15551212 fake\"\n");
1294         fprintf(fp,"display_fake    %s\n\n",(ext->display_fake)?"yes":"no");
1295
1296         fprintf(fp,"# Display caller's name if available. (yes or no)\n");
1297         fprintf(fp,"# example: \"15551212 Axel\"\n");
1298         fprintf(fp,"display_name    %s\n\n",(ext->display_name)?"yes":"no");
1299
1300         fprintf(fp,"# Display menu when '*' and '#' is pressed. The menu shows all prefixes for\n");
1301         fprintf(fp,"# internal dialing by pressing '*' for previous prefix and '#' for next prefix.\n");
1302         fprintf(fp,"# Also the dialed prefix is show on display. (yes or no)\n");
1303         fprintf(fp,"display_menu    %s\n\n",(ext->display_menu)?"yes":"no");
1304
1305         fprintf(fp,"# Display digits as they are interpreted by pbx. (yes or no)\n");
1306         fprintf(fp,"display_dialing %s\n\n",(ext->display_dialing)?"yes":"no");
1307
1308         fprintf(fp,"# Tones directory for announcements and patterns\n");
1309         fprintf(fp,"# Enter nothing for default tones as selected by options.conf.\n");
1310         fprintf(fp,"tones_dir       %s\n\n",ext->tones_dir);
1311
1312         fprintf(fp,"# Record calls to extension's directory. The file is written as wave.\n");
1313         fprintf(fp,"# This must be one of the following:\n");
1314         fprintf(fp,"# off (no recording)\n");
1315         fprintf(fp,"# mono (records wave 16 bit mono, 128kbits/s)\n");
1316         fprintf(fp,"# stereo (records wave 32 bit stereo, 256kbits/s)\n");
1317         fprintf(fp,"# 8bit (records wave 8 bit mono, 64kbits/s)\n");
1318         fprintf(fp,"# law (records xLaw encoded, as specified in options.conf, 64kbps/s)\n");
1319         switch(ext->record)
1320         {
1321                 case CODEC_MONO:
1322                 fprintf(fp,"record          mono\n\n");
1323                 break;
1324                 case CODEC_STEREO:
1325                 fprintf(fp,"record          stereo\n\n");
1326                 break;
1327                 case CODEC_8BIT:
1328                 fprintf(fp,"record          8bit\n\n");
1329                 break;
1330                 case CODEC_LAW:
1331                 fprintf(fp,"record          law\n\n");
1332                 break;
1333                 default:
1334                 fprintf(fp,"record          off\n\n");
1335         }
1336
1337         fprintf(fp,"# Password for callback and login\n");
1338         fprintf(fp,"# Enter nothing if callback and login should not be possible.\n");
1339         fprintf(fp,"password        %s\n\n",ext->password);
1340
1341         fprintf(fp,"# The Answering Machine. Enter the mode of answering machine.\n");
1342         fprintf(fp,"# This must be one of the following:\n");
1343         fprintf(fp,"# normal (plays announcement and records after that)\n");
1344         fprintf(fp,"# parallel (plays announcement and records also DURING announcement.)\n");
1345         fprintf(fp,"# announcement (just plays announcement and hangs up)\n");
1346         switch(ext->vbox_mode)
1347         {
1348                 case VBOX_MODE_PARALLEL:
1349                 fprintf(fp,"vbox_mode       parallel\n\n");
1350                 break;
1351                 case VBOX_MODE_ANNOUNCEMENT:
1352                 fprintf(fp,"vbox_mode       announcement\n\n");
1353                 break;
1354                 default:
1355                 fprintf(fp,"vbox_mode       normal\n\n");
1356         }
1357
1358         fprintf(fp,"# The Answering Machine. Enter the type of codec for recording.\n");
1359         fprintf(fp,"# This must be one of the following:\n");
1360         fprintf(fp,"# law (alaw/ulas codec, as specified in options.conf)\n");
1361         fprintf(fp,"# mono (16 bit mono wave file)\n");
1362         fprintf(fp,"# stereo (16 bit stereo wave file)\n");
1363         fprintf(fp,"# 8bit (8 bit mono wave file)\n");
1364         switch(ext->vbox_codec)
1365         {
1366                 case CODEC_LAW:
1367                 fprintf(fp,"vbox_codec      law\n\n");
1368                 break;
1369                 case CODEC_STEREO:
1370                 fprintf(fp,"vbox_codec      stereo\n\n");
1371                 break;
1372                 case CODEC_8BIT:
1373                 fprintf(fp,"vbox_codec      8bit\n\n");
1374                 break;
1375                 default:
1376                 fprintf(fp,"vbox_codec      mono\n\n");
1377         }
1378
1379         fprintf(fp,"# The Answering Machine. Enter maximum time to record after announcement.\n");
1380         fprintf(fp,"# Leave empty, enter \"infinite\" or give time in seconds.\n");
1381         fprintf(fp,"# Enter nothing if callback and login should not be possible.\n");
1382         if (ext->vbox_time)
1383                 fprintf(fp,"vbox_time       %d\n\n",ext->vbox_time);
1384         else
1385                 fprintf(fp,"vbox_time       infinite\n\n");
1386
1387         fprintf(fp,"# The Answering Machine. Enter mode for display current state.\n");
1388         fprintf(fp,"# This must be one of the following:\n");
1389         fprintf(fp,"# brief (displays brief information, for small displays)\n");
1390         fprintf(fp,"# detailed (displays detailed information, for larger displays)\n");
1391         fprintf(fp,"# off (don't display anything)\n");
1392         switch(ext->vbox_display)
1393         {
1394                 case VBOX_DISPLAY_OFF:
1395                 fprintf(fp,"vbox_display    off\n\n");
1396                 break;
1397                 case VBOX_DISPLAY_DETAILED:
1398                 fprintf(fp,"vbox_display    detailed\n\n");
1399                 break;
1400                 default:
1401                 fprintf(fp,"vbox_display    brief\n\n");
1402         }
1403
1404         fprintf(fp,"# The Answering Machine. Enter type of language: \"english\" or \"german\"\n");
1405         fprintf(fp,"# Display information of the menu, will be provided as specified.\n");
1406         fprintf(fp,"# The menu's voice is located in \"vbox_english\" and \"vbox_german\".\n");
1407         if (ext->vbox_language)
1408                 fprintf(fp,"vbox_language   german\n\n");
1409         else
1410                 fprintf(fp,"vbox_language   english\n\n");
1411
1412         fprintf(fp,"# The Answering Machine. Enter email to send incoming messages to:\n");
1413         fprintf(fp,"# All incoming message will be send to the given address.\n");
1414         fprintf(fp,"# The audio file is attached if \"vbox_email_file\" is 'yes'\n");
1415         fprintf(fp,"vbox_email      %s\n", ext->vbox_email);
1416         fprintf(fp,"vbox_email_file %s\n\n",ext_yesno[ext->vbox_email_file]);
1417
1418         fprintf(fp,"# If audio path is connected prior answering of a call, say 'yes'\n");
1419         fprintf(fp,"# will cause the call to be billed after playing the announcement. (yes or no)\n");
1420         fprintf(fp,"vbox_free       %s\n\n",(ext->vbox_free)?"yes":"no");
1421
1422         fprintf(fp,"# Accept incoming data calls as it would be an audio call.\n");
1423         fprintf(fp,"datacall        %s\n\n",ext_yesno[ext->datacall]);
1424
1425         fprintf(fp,"# Include seconds (time) in the connect message. (Should be always enabled.)\n");
1426         fprintf(fp,"seconds         %s\n\n",ext_yesno[1-ext->no_seconds]);
1427
1428         fprintf(fp,"# Last outgoing and incoming numbers (including prefix)\n");
1429         i = 0;
1430         while(i < MAX_REMEMBER)
1431         {
1432                 if (ext->last_out[i][0])
1433                         fprintf(fp,"last_out        %s\n",ext->last_out[i]);
1434                 i++;
1435         }
1436         i = 0;
1437         while(i < MAX_REMEMBER)
1438         {
1439                 if (ext->last_in[i][0])
1440                         fprintf(fp,"last_in         %s\n",ext->last_in[i]);
1441                 i++;
1442         }
1443         fprintf(fp,"\n");
1444
1445
1446         if (fp) fclose(fp);
1447         return(1);
1448 }
1449
1450
1451 /* write log for extension
1452  *
1453  */
1454 int write_log(char *number, char *callerid, char *calledid, time_t start, time_t stop, int aoce, int cause, int location)
1455 {
1456         char *mon[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
1457         FILE *fp=NULL;
1458         char filename[256];
1459         struct tm *tm;
1460
1461         if (callerid[0] == '\0')
1462                 callerid = "<unknown>";
1463
1464         SPRINT(filename, "%s/%s/%s/log", INSTALL_DATA, options.extensions_dir, number);
1465
1466         if (!(fp = fopen(filename, "a")))
1467         {
1468                 PERROR("Cannot open log: \"%s\"\n", filename);
1469                 return(0);
1470         }
1471
1472         tm = localtime(&start);
1473         fprintf(fp,"%s %2d %04d %02d:%02d:%02d %s", mon[tm->tm_mon], tm->tm_mday, tm->tm_year+1900, tm->tm_hour, tm->tm_min, tm->tm_sec, number);
1474         if (stop)
1475                 fprintf(fp," %2ld:%02ld:%02ld", (stop-start)/3600, (((unsigned long)(stop-start))/60)%60, ((unsigned long)(stop-start))%60);
1476         else
1477                 fprintf(fp," --:--:--");
1478         fprintf(fp," %s -> %s", callerid, calledid);
1479         if (cause >= 1 && cause <=127 && location>=0 && location<=15)
1480                 fprintf(fp," (cause=%d '%s' location=%d '%s')", cause, isdn_cause[cause].german, location, isdn_location[location].german);
1481         fprintf(fp,"\n");
1482
1483         if (fp) fclose(fp);
1484         return(1);
1485 }
1486
1487
1488 /* parse phonebook
1489  *
1490  * reads phone book of extextension and compares the given elements which
1491  * are: abreviation, phone number, name (name is not compared)
1492  * on success a 1 is returned and the pointers of elements are set to the
1493  * result.
1494  */
1495 int parse_phonebook(char *number, char **abbrev_pointer, char **phone_pointer, char **name_pointer)
1496 {
1497         FILE *fp=NULL;
1498         char filename[256];
1499         char *p;
1500         static char abbrev[32], phone[256], name[256];
1501         unsigned int line,i;
1502         char buffer[1024];
1503         int found = 0, found_if_more_digits = 0;
1504
1505         SPRINT(filename, "%s/%s/%s/phonebook", INSTALL_DATA, options.extensions_dir, number);
1506
1507         if (!(fp = fopen(filename, "r")))
1508         {
1509                 PERROR("Cannot open phonebook: \"%s\"\n", filename);
1510                 return(0);
1511         }
1512
1513         line=0;
1514         while((fgets(buffer, sizeof(buffer), fp)))
1515         {
1516                 line++;
1517                 buffer[sizeof(buffer)-1] = '\0';
1518                 if (buffer[0]) buffer[strlen(buffer)-1] = '\0';
1519                 p = buffer;
1520
1521                 while(*p <= 32) /* skip spaces */
1522                 {
1523                         if (*p == 0)
1524                                 break;
1525                         p++;
1526                 }
1527                 if (*p==0 || *p=='#') /* ignore comments and empty line */
1528                         continue;
1529
1530                 abbrev[0]=0;
1531                 phone[0]=0;
1532                 name[0]=0;
1533
1534                 i=0; /* read abbrev */
1535                 while(*p > 32)
1536                 {
1537                         if (i+1 >= sizeof(abbrev))
1538                         {
1539                                 PERROR_RUNTIME("Error in %s (line %d): abbrev too long.\n",filename,line);
1540                                 break;
1541                         }
1542                         abbrev[i+1] = '\0';
1543                         abbrev[i++] = *p++;
1544                 }
1545
1546                 while(*p <= 32) /* skip spaces */
1547                 {
1548                         if (*p == 0)
1549                                 break;
1550                         p++;
1551                 }
1552
1553                 if (*p!=0 && *p!='#') /* phone */
1554                 {
1555                         i=0; /* read phone */
1556                         while(*p > 32)
1557                         {
1558                                 if (i+1 >= sizeof(phone))
1559                                 {
1560                                         PERROR_RUNTIME("Error in %s (line %d): phone too long.\n",filename,line);
1561                                         break;
1562                                 }
1563                                 phone[i+1] = '\0';
1564                                 phone[i++] = *p++;
1565                         }
1566                         while(*p <= 32) /* skip spaces */
1567                         {
1568                                 if (*p == 0)
1569                                         break;
1570                                 p++;
1571                         }
1572                 }
1573
1574                 if (*p!=0 && *p!='#') /* name */
1575                 {
1576                         i=0; /* read name */
1577                         while(*p > 0)
1578                         {
1579                                 if (i+1 >= sizeof(name))
1580                                 {
1581                                         PERROR_RUNTIME("Error in %s (line %d): name too long.\n",filename,line);
1582                                         break;
1583                                 }
1584                                 name[i+1] = '\0';
1585                                 name[i++] = *p++;
1586                         }
1587                 }
1588
1589                 if (*abbrev_pointer)
1590                 {
1591                         if (!strncmp(*abbrev_pointer, abbrev, strlen(*abbrev_pointer)))
1592                         {
1593                                 /* may match if abbreviation is longer */
1594                                 found_if_more_digits = 1;
1595                         }
1596                         if (!!strcasecmp(*abbrev_pointer, abbrev))
1597                                 continue;
1598                 }
1599                 if (*phone_pointer)
1600                         if (!!strcasecmp(*phone_pointer, phone))
1601                                 continue;
1602                 if (*name_pointer)
1603                         if (!!strcasecmp(*name_pointer, name))
1604                                 continue;
1605
1606                 found = 1;
1607                 break; /* found entry */
1608         }
1609
1610         if (fp) fclose(fp);
1611
1612         if (found)
1613         {
1614                 *abbrev_pointer = abbrev;
1615                 *phone_pointer = phone;
1616                 *name_pointer = name;
1617         }
1618
1619         if (found == 0)
1620         {
1621                 if (found_if_more_digits)
1622                         found = -1;
1623         }
1624         return(found);
1625 }
1626
1627 /* parsing secrets file
1628  *
1629  * 'number' specifies the externsion number, not the caller id
1630  * 'remote_id' specifies the dialed number, or the caller id for incoming calls
1631  * the result is the auth, crypt and key string, and 1 is returned.
1632  * on failure or not matching number, the 0 is returned
1633  */
1634 int parse_secrets(char *number, char *remote_id, char **auth_pointer, char **crypt_pointer, char **key_pointer)
1635 {
1636         FILE *fp=NULL;
1637         char filename[256];
1638         char *p;
1639         char remote[128];
1640         static char auth[64], crypt[64], key[4096];
1641         unsigned int line,i;
1642         char buffer[4096];
1643         int found = 0;
1644
1645         SPRINT(filename, "%s/%s/%s/secrets", INSTALL_DATA, options.extensions_dir, number);
1646
1647         if (!(fp = fopen(filename, "r")))
1648         {
1649                 PERROR("Cannot open secrets: \"%s\"\n", filename);
1650                 return(0);
1651         }
1652
1653         line=0;
1654         while((fgets(buffer, sizeof(buffer), fp)))
1655         {
1656                 line++;
1657                 buffer[sizeof(buffer)-1] = '\0';
1658                 if (buffer[0]) buffer[strlen(buffer)-1] = '\0';
1659                 p = buffer;
1660
1661                 while(*p <= 32) /* skip spaces */
1662                 {
1663                         if (*p == 0)
1664                                 break;
1665                         p++;
1666                 }
1667                 if (*p==0 || *p=='#') /* ignore comments and empty line */
1668                         continue;
1669
1670                 remote[0]=0;
1671                 auth[0]=0;
1672                 crypt[0]=0;
1673                 key[0]=0;
1674
1675                 i=0; /* read auth */
1676                 while(*p > 32)
1677                 {
1678                         if (i+1 >= sizeof(remote))
1679                         {
1680                                 PERROR_RUNTIME("Error in %s (line %d): remote too long.\n",filename,line);
1681                                 break;
1682                         }
1683                         remote[i+1] = '\0';
1684                         remote[i++] = *p++;
1685                 }
1686
1687                 while(*p <= 32) /* skip spaces */
1688                 {
1689                         if (*p == 0)
1690                                 break;
1691                         p++;
1692                 }
1693
1694                 if (*p!=0 && *p!='#') /* auth */
1695                 {
1696                         i=0; /* read auth */
1697                         while(*p > 32)
1698                         {
1699                                 if (i+1 >= sizeof(auth))
1700                                 {
1701                                         PERROR_RUNTIME("Error in %s (line %d): auth too long.\n",filename,line);
1702                                         break;
1703                                 }
1704                                 auth[i+1] = '\0';
1705                                 auth[i++] = *p++;
1706                         }
1707                         while(*p <= 32) /* skip spaces */
1708                         {
1709                                 if (*p == 0)
1710                                         break;
1711                                 p++;
1712                         }
1713                 }
1714
1715                 if (*p!=0 && *p!='#') /* crypt */
1716                 {
1717                         i=0; /* read crypt */
1718                         while(*p > 32)
1719                         {
1720                                 if (i+1 >= sizeof(crypt))
1721                                 {
1722                                         PERROR_RUNTIME("Error in %s (line %d): crypt too long.\n",filename,line);
1723                                         break;
1724                                 }
1725                                 crypt[i+1] = '\0';
1726                                 crypt[i++] = *p++;
1727                         }
1728                         while(*p <= 32) /* skip spaces */
1729                         {
1730                                 if (*p == 0)
1731                                         break;
1732                                 p++;
1733                         }
1734                 }
1735
1736                 if (*p!=0 && *p!='#') /* key */
1737                 {
1738                         i=0; /* read key */
1739                         while(*p > 0)
1740                         {
1741                                 if (i+1 >= sizeof(key))
1742                                 {
1743                                         PERROR_RUNTIME("Error in %s (line %d): key too long.\n",filename,line);
1744                                         break;
1745                                 }
1746                                 key[i+1] = '\0';
1747                                 key[i++] = *p++;
1748                         }
1749                 }
1750 //printf("COMPARING: '%s' with '%s' %s %s %s\n", remote_id, remote, auth, crypt, key);
1751
1752                 if (!!strcasecmp(remote, remote_id))
1753                         continue;
1754
1755                 found = 1;
1756                 break; /* found entry */
1757         }
1758
1759         if (fp) fclose(fp);
1760
1761         if (found)
1762         {
1763                 *auth_pointer = auth;
1764                 *crypt_pointer = crypt;
1765                 *key_pointer = key;
1766         }
1767
1768         return(found);
1769 }
1770
1771 /* parse directory
1772  *
1773  * the caller id is given and the name is returned. if the name is not found,
1774  * NULL is returned.
1775  * on success a 1 is returned and the pointers of elements are set to the
1776  * result.
1777  */
1778 char *parse_directory(char *number, int type)
1779 {
1780         FILE *fp=NULL;
1781         char filename[256];
1782         char *p;
1783         static char phone[32], name[64];
1784         unsigned int line,i;
1785         char buffer[256];
1786         int found = 0;
1787
1788         SPRINT(filename, "%s/directory.list", INSTALL_DATA);
1789
1790         if (!(fp = fopen(filename, "r")))
1791         {
1792                 PERROR("Cannot open directory: \"%s\"\n", filename);
1793                 return(NULL);
1794         }
1795
1796         line=0;
1797         while((fgets(buffer, sizeof(buffer), fp)))
1798         {
1799                 line++;
1800                 buffer[sizeof(buffer)-1] = '\0';
1801                 if (buffer[0]) buffer[strlen(buffer)-1] = '\0';
1802                 p = buffer;
1803
1804                 while(*p <= 32) /* skip spaces */
1805                 {
1806                         if (*p == 0)
1807                                 break;
1808                         p++;
1809                 }
1810                 if (*p==0 || *p=='#') /* ignore comments and empty line */
1811                         continue;
1812
1813                 phone[0]=0;
1814                 name[0]=0;
1815
1816                 i=0; /* read number */
1817                 while(*p > 32)
1818                 {
1819                         if (i+1 >= sizeof(phone))
1820                         {
1821                                 PERROR_RUNTIME("Error in %s (line %d): number too long.\n",filename,line);
1822                                 break;
1823                         }
1824                         phone[i+1] = '\0';
1825                         phone[i++] = *p++;
1826                 }
1827
1828                 while(*p <= 32) /* skip spaces */
1829                 {
1830                         if (*p == 0)
1831                                 break;
1832                         p++;
1833                 }
1834
1835                 i=0; /* read name */
1836                 while(*p >= 32)
1837                 {
1838                         if (i+1 >= sizeof(name))
1839                         {
1840                                 PERROR_RUNTIME("Error in %s (line %d): name too long.\n",filename,line);
1841                                 break;
1842                         }
1843                         name[i+1] = '\0';
1844                         name[i++] = *p++;
1845                 }
1846
1847                 if (phone[0] == 'i')
1848                 {
1849                         if (type != INFO_NTYPE_INTERNATIONAL)
1850                                 continue;
1851                         if (!strcmp(number, phone+1))
1852                         {
1853                                 found = 1;
1854                                 break;
1855                         }
1856                         continue;
1857                 }
1858                 if (phone[0] == 'n')
1859                 {
1860                         if (type != INFO_NTYPE_NATIONAL)
1861                                 continue;
1862                         if (!strcmp(number, phone+1))
1863                         {
1864                                 found = 1;
1865                                 break;
1866                         }
1867                         continue;
1868                 }
1869                 if (phone[0] == 's')
1870                 {
1871                         if (type==INFO_NTYPE_NATIONAL || type==INFO_NTYPE_INTERNATIONAL)
1872                                 continue;
1873                         if (!strcmp(number, phone+1))
1874                         {
1875                                 found = 1;
1876                                 break;
1877                         }
1878                         continue;
1879                 }
1880                 if (!strncmp(phone, options.international, strlen(options.international)))
1881                 {
1882                         if (type != INFO_NTYPE_INTERNATIONAL)
1883                                 continue;
1884                         if (!strcmp(number, phone+strlen(options.international)))
1885                         {
1886                                 found = 1;
1887                                 break;
1888                         }
1889                         continue;
1890                 }
1891                 if (!options.national[0]) /* no national prefix */
1892                 {
1893                         if (type == INFO_NTYPE_INTERNATIONAL)
1894                                 continue;
1895                         if (!strcmp(number, phone))
1896                         {
1897                                 found = 1;
1898                                 break;
1899                         }
1900                         continue;
1901                 }
1902                 if (!strncmp(phone, options.national, strlen(options.national)))
1903                 {
1904                         if (type != INFO_NTYPE_NATIONAL)
1905                                 continue;
1906                         if (!strcmp(number, phone+strlen(options.national)))
1907                         {
1908                                 found = 1;
1909                                 break;
1910                         }
1911                         continue;
1912                 }
1913                 if (type==INFO_NTYPE_NATIONAL || type==INFO_NTYPE_INTERNATIONAL)
1914                         continue;
1915                 if (!strcmp(number, phone))
1916                 {
1917                         found = 1;
1918                         break;
1919                 }
1920         }
1921
1922         if (fp) fclose(fp);
1923
1924         if (found)
1925                 return(name);
1926         else
1927                 return(NULL);
1928 }
1929
1930 /* parse callbackauth
1931  *
1932  * searches for the given caller id and returns 1 == true or 0 == false
1933  */
1934 int parse_callbackauth(char *number, struct caller_info *callerinfo)
1935 {
1936         FILE *fp = NULL;
1937         char filename[256];
1938         char *p;
1939         unsigned int line,i;
1940         char buffer[256];
1941         static char caller_type[32], caller_id[64];
1942         int found = 0;
1943
1944         SPRINT(filename, "%s/%s/%s/callbackauth", INSTALL_DATA, options.extensions_dir, number);
1945
1946         if (!(fp = fopen(filename, "r")))
1947         {
1948                 PDEBUG(DEBUG_EPOINT, "Cannot open callbackauth: \"%s\"\n", filename);
1949                 return(0);
1950         }
1951
1952         line=0;
1953         while((fgets(buffer, sizeof(buffer), fp)))
1954         {
1955                 line++;
1956                 buffer[sizeof(buffer)-1] = '\0';
1957                 if (buffer[0]) buffer[strlen(buffer)-1] = '\0';
1958                 p = buffer;
1959
1960                 while(*p <= 32) /* skip spaces */
1961                 {
1962                         if (*p == 0)
1963                                 break;
1964                         p++;
1965                 }
1966                 if (*p==0 || *p=='#') /* ignore comments and empty line */
1967                         continue;
1968
1969                 caller_type[0]=0;
1970                 caller_id[0]=0;
1971
1972                 i=0; /* read caller_type */
1973                 while(*p > 32)
1974                 {
1975                         if (i+1 >= sizeof(caller_type))
1976                         {
1977                                 PERROR_RUNTIME("Error in %s (line %d): caller_type too long.\n",filename,line);
1978                                 break;
1979                         }
1980                         caller_type[i+1] = '\0';
1981                         caller_type[i++] = *p++;
1982                 }
1983
1984                 while(*p <= 32) /* skip spaces */
1985                 {
1986                         if (*p == 0)
1987                                 break;
1988                         p++;
1989                 }
1990
1991                 if (*p!=0 && *p!='#') /* caller_id */
1992                 {
1993                         i=0; /* read caller_id */
1994                         while(*p > 32)
1995                         {
1996                                 if (i+1 >= sizeof(caller_id))
1997                                 {
1998                                         PERROR_RUNTIME("Error in %s (line %d): caller_id too long.\n",filename,line);
1999                                         break;
2000                                 }
2001                                 caller_id[i+1] = '\0';
2002                                 caller_id[i++] = *p++;
2003                         }
2004                         // ignoring more
2005                 }
2006
2007                 if (caller_type[0]=='\0' && caller_id[0]=='\0')
2008                         continue;
2009
2010                 if (atoi(caller_type) != callerinfo->ntype)
2011                         continue;
2012
2013                 if (!!strcmp(caller_id, callerinfo->id))
2014                         continue;
2015
2016                 found = 1;
2017                 break; /* found entry */
2018         }
2019
2020         if (fp) fclose(fp);
2021
2022         if (found)
2023                 return(1);
2024         return(0);
2025 }
2026
2027
2028 /* append line to callbackauth
2029  *
2030  */
2031 void append_callbackauth(char *number, struct caller_info *callerinfo)
2032 {
2033         FILE *fp = NULL;
2034         char filename[256];
2035
2036         SPRINT(filename, "%s/%s/%s/callbackauth", INSTALL_DATA, options.extensions_dir, number);
2037
2038         if (callerinfo->id[0]=='\0')
2039         {
2040                 PERROR("caller has no id.\n");
2041                 return;
2042         }
2043         if (!(fp = fopen(filename, "a")))
2044         {
2045                 PERROR("Cannot open callbackauth: \"%s\"\n", filename);
2046                 return;
2047         }
2048
2049         fprintf(fp, "%6d  %s\n", callerinfo->ntype, callerinfo->id);
2050
2051         fclose(fp);
2052
2053 }
2054
2055