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