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