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