another bunch of include removals (errno.h and asterisk/logger.h)
[asterisk/asterisk.git] / funcs / func_realtime.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2005-2006, BJ Weschke. All rights reserved.
5  * 
6  * BJ Weschke <bweschke@btwtech.com>
7  * 
8  * This code is released by the author with no restrictions on usage. 
9  *
10  * See http://www.asterisk.org for more information about
11  * the Asterisk project. Please do not directly contact
12  * any of the maintainers of this project for assistance;
13  * the project provides a web site, mailing lists and IRC
14  * channels for your use.
15  *
16  */
17
18 /*! \file
19  *
20  * \brief REALTIME dialplan function
21  * 
22  * \author BJ Weschke <bweschke@btwtech.com>
23  * 
24  * \ingroup functions
25  */
26
27 #include "asterisk.h"
28
29 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
30
31 #include "asterisk/file.h"
32 #include "asterisk/channel.h"
33 #include "asterisk/pbx.h"
34 #include "asterisk/options.h"
35 #include "asterisk/config.h"
36 #include "asterisk/module.h"
37 #include "asterisk/lock.h"
38 #include "asterisk/utils.h"
39 #include "asterisk/app.h"
40
41 static int function_realtime_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) 
42 {
43         struct ast_variable *var, *head;
44         struct ast_str *out;
45         size_t resultslen;
46         int n;
47         AST_DECLARE_APP_ARGS(args,
48                 AST_APP_ARG(family);
49                 AST_APP_ARG(fieldmatch);
50                 AST_APP_ARG(value);
51                 AST_APP_ARG(delim1);
52                 AST_APP_ARG(delim2);
53         );
54
55         if (ast_strlen_zero(data)) {
56                 ast_log(LOG_WARNING, "Syntax: REALTIME(family,fieldmatch[,value[,delim1[,delim2]]]) - missing argument!\n");
57                 return -1;
58         }
59
60         AST_STANDARD_APP_ARGS(args, data);
61
62         if (!args.delim1)
63                 args.delim1 = ",";
64         if (!args.delim2)
65                 args.delim2 = "=";
66
67         if (chan)
68                 ast_autoservice_start(chan);
69
70         head = ast_load_realtime_all(args.family, args.fieldmatch, args.value, NULL);
71
72         if (!head)
73                 if (chan)
74                         ast_autoservice_stop(chan);
75                 return -1;
76
77         resultslen = 0;
78         n = 0;
79         for (var = head; var; n++, var = var->next)
80                 resultslen += strlen(var->name) + strlen(var->value);
81         /* add space for delimiters and final '\0' */
82         resultslen += n * (strlen(args.delim1) + strlen(args.delim2)) + 1;
83
84         out = ast_str_alloca(resultslen);
85         for (var = head; var; var = var->next)
86                 ast_str_append(&out, 0, "%s%s%s%s", var->name, args.delim2, var->value, args.delim1);
87         ast_copy_string(buf, out->str, len);
88
89         if (chan)
90                 ast_autoservice_stop(chan);
91
92         return 0;
93 }
94
95 static int function_realtime_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
96 {
97         int res = 0;
98         AST_DECLARE_APP_ARGS(args,
99                 AST_APP_ARG(family);
100                 AST_APP_ARG(fieldmatch);
101                 AST_APP_ARG(value);
102                 AST_APP_ARG(field);
103         );
104
105         if (ast_strlen_zero(data)) {
106                 ast_log(LOG_WARNING, "Syntax: REALTIME(family,fieldmatch,value,newcol) - missing argument!\n");
107                 return -1;
108         }
109
110         if (chan)
111                 ast_autoservice_start(chan);
112
113         AST_STANDARD_APP_ARGS(args, data);
114
115         res = ast_update_realtime(args.family, args.fieldmatch, args.value, args.field, (char *)value, NULL);
116
117         if (res < 0) {
118                 ast_log(LOG_WARNING, "Failed to update. Check the debug log for possible data repository related entries.\n");
119         }
120
121         if (chan)
122                 ast_autoservice_stop(chan);
123
124         return 0;
125 }
126
127 struct ast_custom_function realtime_function = {
128         .name = "REALTIME",
129         .synopsis = "RealTime Read/Write Functions",
130         .syntax = "REALTIME(family,fieldmatch[,value[,delim1[,delim2]]]) on read\n"
131                   "REALTIME(family,fieldmatch,value,field) on write",
132         .desc = "This function will read or write values from/to a RealTime repository.\n"
133                 "REALTIME(....) will read names/values from the repository, and \n"
134                 "REALTIME(....)= will write a new value/field to the repository. On a\n"
135                 "read, this function returns a delimited text string. The name/value \n"
136                 "pairs are delimited by delim1, and the name and value are delimited \n"
137                 "between each other with delim2. The default for delim1 is ',' and   \n"
138                 "the default for delim2 is '='. If there is no match, NULL will be   \n"
139                 "returned by the function. On a write, this function will always     \n"
140                 "return NULL. \n",
141         .read = function_realtime_read,
142         .write = function_realtime_write,
143 };
144
145 static int unload_module(void)
146 {
147         return ast_custom_function_unregister(&realtime_function);
148 }
149
150 static int load_module(void)
151 {
152         return ast_custom_function_register(&realtime_function);
153 }
154
155 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Read/Write values from a RealTime repository");