the last round of file version tags
[asterisk/asterisk.git] / apps / app_forkcdr.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Fork CDR application
5  * Copyright Anthony Minessale anthmct@yahoo.com
6  * Development of this app Sponsered/Funded  by TAAN Softworks Corp
7  * 
8  * This program is free software, distributed under the terms of
9  * the GNU General Public License
10  */
11
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <string.h>
15 #include <pthread.h>
16
17 #include "asterisk.h"
18
19 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
20
21 #include "asterisk/file.h"
22 #include "asterisk/logger.h"
23 #include "asterisk/channel.h"
24 #include "asterisk/pbx.h"
25 #include "asterisk/cdr.h"
26 #include "asterisk/module.h"
27
28 static char *tdesc = "Fork The CDR into 2 separate entities.";
29 static char *app = "ForkCDR";
30 static char *synopsis = 
31 "Forks the Call Data Record";
32 static char *descrip = 
33 "  ForkCDR([options]):  Causes the Call Data Record to fork an additional\n"
34         "cdr record starting from the time of the fork call\n"
35 "If the option 'v' is passed all cdr variables will be passed along also.\n"
36 "";
37
38
39 STANDARD_LOCAL_USER;
40
41 LOCAL_USER_DECL;
42
43
44 static void ast_cdr_clone(struct ast_cdr *cdr) 
45 {
46         struct ast_cdr *newcdr = ast_cdr_alloc();
47         memcpy(newcdr,cdr,sizeof(struct ast_cdr));
48         ast_cdr_append(cdr,newcdr);
49         gettimeofday(&newcdr->start, NULL);
50         memset(&newcdr->answer, 0, sizeof(newcdr->answer));
51         memset(&newcdr->varshead, 0, sizeof(newcdr->varshead));
52         ast_cdr_copy_vars(newcdr, cdr);
53         if (!ast_test_flag(cdr, AST_CDR_FLAG_KEEP_VARS)) {
54                 ast_cdr_free_vars(cdr, 0);
55         }
56         newcdr->disposition = AST_CDR_NOANSWER;
57         ast_set_flag(cdr, AST_CDR_FLAG_CHILD|AST_CDR_FLAG_LOCKED);
58 }
59
60 static void ast_cdr_fork(struct ast_channel *chan) 
61 {
62         if(chan && chan->cdr) {
63                 ast_cdr_clone(chan->cdr);
64         }
65 }
66
67 static int forkcdr_exec(struct ast_channel *chan, void *data)
68 {
69         int res=0;
70         struct localuser *u;
71         LOCAL_USER_ADD(u);
72         if (data && !ast_strlen_zero(data))
73                 ast_set2_flag(chan->cdr, strchr((char *)data, 'v'), AST_CDR_FLAG_KEEP_VARS);
74         
75         ast_cdr_fork(chan);
76
77         LOCAL_USER_REMOVE(u);
78         return res;
79 }
80
81 int unload_module(void)
82 {
83         STANDARD_HANGUP_LOCALUSERS;
84         return ast_unregister_application(app);
85 }
86
87 int load_module(void)
88 {
89         return ast_register_application(app, forkcdr_exec, synopsis, descrip);
90 }
91
92 char *description(void)
93 {
94         return tdesc;
95 }
96
97 int usecount(void)
98 {
99         int res;
100         STANDARD_USECOUNT(res);
101         return res;
102 }
103
104 char *key()
105 {
106         return ASTERISK_GPL_KEY;
107 }