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