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