Browse code

- GET_CPL FIFO command added - all FIFO commands return status + comments via reply file

Bogdan-Andrei Iancu authored on 20/10/2003 15:37:29
Showing 5 changed files
... ...
@@ -263,6 +263,10 @@ static int cpl_init(void)
263 263
 		LOG(L_CRIT,"ERROR:cpl_init: cannot register REMOVE_CPL fifo cmd!\n");
264 264
 		goto error;
265 265
 	}
266
+	if (register_fifo_cmd( cpl_get, "GET_CPL", 0)!=1) {
267
+		LOG(L_CRIT,"ERROR:cpl_init: cannot register GET_CPL fifo cmd!\n");
268
+		goto error;
269
+	}
266 270
 
267 271
 	/* build a pipe for sending commands to aux proccess */
268 272
 	if ( pipe(cpl_cmd_pipe)==-1 ) {
... ...
@@ -623,8 +627,8 @@ static inline int do_script_download(struct sip_msg *msg)
623 627
 {
624 628
 	struct lump_rpl *ct_type;
625 629
 	struct lump_rpl *body;
626
-	str  user;
627
-	str script;
630
+	str  user  = {0,0};
631
+	str script = {0,0};
628 632
 
629 633
 	/* get the destination user name */
630 634
 	if (get_dest_user( msg, &user)==-1)
... ...
@@ -644,7 +648,7 @@ static inline int do_script_download(struct sip_msg *msg)
644 648
 	}
645 649
 	add_lump_rpl(  msg, ct_type);
646 650
 
647
-	if (script.len!=0 && script.s!=0) {
651
+	if (script.s!=0) {
648 652
 		/*DBG("script len=%d\n--------\n%.*s\n--------\n",
649 653
 			script.len, script.len, script.s);*/
650 654
 		/* user has a script -> add a body lump */
... ...
@@ -655,6 +659,9 @@ static inline int do_script_download(struct sip_msg *msg)
655 659
 			cpl_err = &intern_err;
656 660
 			goto error;
657 661
 		}
662
+		/* build_lump_rpl duplicates the added text, so free the original */
663
+		shm_free( script.s );
664
+		/* add the lump */
658 665
 		if (add_lump_rpl( msg, body)==-1) {
659 666
 			LOG(L_CRIT,"BUG:cpl-c:do_script_download: body lump "
660 667
 				"already added\n");
... ...
@@ -665,6 +672,8 @@ static inline int do_script_download(struct sip_msg *msg)
665 672
 
666 673
 	return 0;
667 674
 error:
675
+	if (script.s)
676
+		shm_free(script.s);
668 677
 	return -1;
669 678
 }
670 679
 
... ...
@@ -79,10 +79,11 @@ int get_user_script( db_con_t *db_hdl, str *user, str *script, char* key)
79 79
 			script->len = res->rows[0].values[0].val.blob_val.len;
80 80
 			script->s = shm_malloc( script->len );
81 81
 			if (!script->s) {
82
-				LOG(L_ERR,"ERROR:cpl-c:get_user_script: no more free sh_mem\n");
82
+				LOG(L_ERR,"ERROR:cpl-c:get_user_script: no free sh_mem\n");
83 83
 				goto error;
84 84
 			}
85
-			memcpy(script->s,res->rows[0].values[0].val.blob_val.s,script->len);
85
+			memcpy( script->s, res->rows[0].values[0].val.blob_val.s,
86
+				script->len);
86 87
 		}
87 88
 	}
88 89
 
... ...
@@ -33,6 +33,7 @@
33 33
 
34 34
 
35 35
 #include <stdio.h>
36
+#include <sys/uio.h>
36 37
 #include <stdlib.h>
37 38
 #include <unistd.h>
38 39
 #include <sys/types.h>
... ...
@@ -45,6 +46,7 @@
45 46
 #include "../../dprint.h"
46 47
 #include "../../fifo_server.h"
47 48
 #include "../../mem/mem.h"
49
+#include "../../mem/shm_mem.h"
48 50
 #include "cpl_db.h"
49 51
 #include "cpl_parser.h"
50 52
 #include "cpl_loader.h"
... ...
@@ -56,7 +58,7 @@ extern db_con_t* db_hdl;
56 58
 
57 59
 
58 60
 
59
-
61
+#if 0
60 62
 /* debug function -> write into a file the content of a str stuct. */
61 63
 int write_to_file(char *filename, str *buf)
62 64
 {
... ...
@@ -83,6 +85,7 @@ int write_to_file(char *filename, str *buf)
83 85
 error:
84 86
 	return -1;
85 87
 }
88
+#endif
86 89
 
87 90
 
88 91
 
... ...
@@ -157,28 +160,32 @@ error:
157 160
 
158 161
 
159 162
 
160
-/* Writes the cpl log into the given file.
163
+/* Writes an aray of texts into the given response file.
164
+ * Accepts also empty texts, case in which it will be created an empty
165
+ * response file.
161 166
  */
162
-void write_log_to_file( char *response_file, str *log )
167
+void write_to_file( char *file, str *txt, int n )
163 168
 {
164 169
 	int fd;
165 170
 
166 171
 	/* open file for write */
167
-	fd = open( response_file, O_WRONLY|O_CREAT|O_TRUNC/*|O_NOFOLLOW*/, 0600 );
172
+	fd = open( file, O_WRONLY|O_CREAT|O_TRUNC/*|O_NOFOLLOW*/, 0600 );
168 173
 	if (fd==-1) {
169
-		LOG(L_ERR,"ERROR:cpl-c:write_logs_to_file: cannot open response file "
170
-			"<%s>: %s\n", response_file, strerror(errno));
174
+		LOG(L_ERR,"ERROR:cpl-c:write_to_file: cannot open response file "
175
+			"<%s>: %s\n", file, strerror(errno));
171 176
 		return;
172 177
 	}
173 178
 
174
-	/* write the log */
179
+	/* write the txt, if any */
180
+	if (n>0) {
175 181
 again:
176
-	if ( write( fd, log->s, log->len)==-1) {
177
-		if (errno==EINTR) {
178
-			goto again;
179
-		} else {
180
-			LOG(L_ERR,"ERROR:cpl-c:write_logs_to_file: write failed: %s\n",
181
-				strerror(errno) );
182
+		if ( writev( fd, (struct iovec*)txt, n)==-1) {
183
+			if (errno==EINTR) {
184
+				goto again;
185
+			} else {
186
+				LOG(L_ERR,"ERROR:cpl-c:write_logs_to_file: writev failed: "
187
+					"%s\n", strerror(errno) );
188
+			}
182 189
 		}
183 190
 	}
184 191
 
... ...
@@ -200,6 +207,8 @@ again:
200 207
  * For the given user, loads the XML cpl file, compile it into binary format
201 208
  * and store both format into database
202 209
  */
210
+#define FILE_LOAD_ERR "Error: Cannot read CPL file.\n"
211
+#define DB_SAVE_ERR   "Error: Cannot save CPL to database.\n"
203 212
 int cpl_load( FILE *fifo_stream, char *response_file )
204 213
 {
205 214
 	static char user[MAX_STATIC_BUF];
... ...
@@ -208,10 +217,18 @@ int cpl_load( FILE *fifo_stream, char *response_file )
208 217
 	int cpl_file_len;
209 218
 	str xml = {0,0};
210 219
 	str bin = {0,0};
211
-	str log = {0,0};
220
+	str enc_log = {0,0};
221
+	str logs[2];
212 222
 
213 223
 	DBG("DEBUG:cpl-c:cpl_load: \"LOAD_CPL\" FIFO commnad received!\n");
214 224
 
225
+	/* check the name of the response file */
226
+	if (response_file==0) {
227
+		LOG(L_ERR,"ERROR:cpl-c:cpl_load: no reply file received from "
228
+			"FIFO command\n");
229
+		goto error;
230
+	}
231
+
215 232
 	/* first line must be the username */
216 233
 	if (read_line( user, MAX_STATIC_BUF-1 , fifo_stream, &user_len )!=1 ||
217 234
 	user_len<=0) {
... ...
@@ -234,32 +251,41 @@ int cpl_load( FILE *fifo_stream, char *response_file )
234 251
 
235 252
 	/* load the xml file - this function will allocted a buff for the loading
236 253
 	 * the cpl file and attach it to xml.s -> don't forget to free it! */
237
-	if (load_file( cpl_file, &xml)!=1)
238
-		goto error;
254
+	if (load_file( cpl_file, &xml)!=1) {
255
+		logs[1].s = FILE_LOAD_ERR;
256
+		logs[1].len = strlen( FILE_LOAD_ERR );
257
+		goto error1;
258
+	}
239 259
 
240 260
 	/* get the binary coding for the XML file */
241
-	if (encodeCPL( &xml, &bin, &log)!=1) {
242
-		if (log.len && log.s && response_file )
243
-			write_log_to_file( response_file, &log);
261
+	if (encodeCPL( &xml, &bin, &enc_log)!=1) {
262
+		logs[1] = enc_log;
244 263
 		goto error1;
245 264
 	}
265
+	logs[1] = enc_log;
246 266
 
247 267
 	/* write both the XML and binary formats into database */
248
-	if (write_to_db( db_hdl, user, &xml, &bin)!=1)
268
+	if (write_to_db( db_hdl, user, &xml, &bin)!=1) {
269
+		logs[1].s = DB_SAVE_ERR;
270
+		logs[1].len = strlen( DB_SAVE_ERR );
249 271
 		goto error1;
272
+	}
250 273
 
251 274
 	/* free the memory used for storing the cpl script in XML format */
252 275
 	pkg_free( xml.s );
253 276
 
254
-	/* if any logs were generated -> dump them into response file */
255
-	if (log.len && log.s && response_file )
256
-		write_log_to_file( response_file, &log);
257
-
258
-	if (log.s) pkg_free ( log.s );
277
+	/* everything was OK -> dump the logs into response file */
278
+	logs[0].s = "OK\n";
279
+	logs[0].len = 3;
280
+	write_to_file( response_file, logs, 2);
281
+	if (enc_log.s) pkg_free ( enc_log.s );
259 282
 	return 1;
260 283
 error1:
261
-	if (log.s) pkg_free ( log.s );
262
-	pkg_free ( xml.s );
284
+	logs[0].s = "ERROR\n";
285
+	logs[0].len = 6;
286
+	write_to_file( response_file, logs, 2);
287
+	if (enc_log.s) pkg_free ( enc_log.s );
288
+	if (xml.s) pkg_free ( xml.s );
263 289
 error:
264 290
 	return -1;
265 291
 }
... ...
@@ -276,13 +302,22 @@ error:
276 302
  * For the given user, remove the entire database record
277 303
  * (XML cpl and binary cpl); user with empty cpl scripts are not accepted
278 304
  */
305
+#define DB_RMV_ERR   "Error: Database remove failed.\n"
279 306
 int cpl_remove( FILE *fifo_stream, char *response_file )
280 307
 {
281 308
 	static char user[MAX_STATIC_BUF];
282 309
 	int user_len;
310
+	str logs[2];
283 311
 
284 312
 	DBG("DEBUG:cpl-c:cpl_remove: \"REMOVE_CPL\" FIFO commnad received!\n");
285 313
 
314
+	/* check the name of the response file */
315
+	if (response_file==0) {
316
+		LOG(L_ERR,"ERROR:cpl-c:cpl_remove: no reply file received from "
317
+			"FIFO command\n");
318
+		goto error;
319
+	}
320
+
286 321
 	/* first line must be the username */
287 322
 	if (read_line( user, MAX_STATIC_BUF-1 , fifo_stream, &user_len )!=1 ||
288 323
 	user_len<=0) {
... ...
@@ -293,13 +328,72 @@ int cpl_remove( FILE *fifo_stream, char *response_file )
293 328
 	user[user_len] = 0;
294 329
 	DBG("DEBUG:cpl-c:cpl_remove: user=%.*s\n",user_len,user);
295 330
 
296
-	if (rmv_from_db( db_hdl, user)!=1)
331
+	if (rmv_from_db( db_hdl, user)!=1) {
332
+		logs[1].s = DB_RMV_ERR;
333
+		logs[1].len = sizeof(DB_RMV_ERR);
334
+		goto error1;
335
+	}
336
+
337
+	logs[0].s = "OK\n";
338
+	logs[0].len = 3;
339
+	write_to_file( response_file, logs, 1);
340
+	return 1;
341
+error1:
342
+	logs[0].s = "ERROR\n";
343
+	logs[0].len = 6;
344
+	write_to_file( response_file, logs, 2);
345
+error:
346
+	return -1;
347
+}
348
+
349
+
350
+
351
+/* Triggered by fifo server -> implements GET_CPL command
352
+ * Command format:
353
+ * -----------------------
354
+ *   :GET_CPL:
355
+ *   username
356
+ *   <empty line>
357
+ * -----------------------
358
+ * For the given user, return the CPL script in XML format
359
+ */
360
+int cpl_get( FILE *fifo_stream, char *response_file )
361
+{
362
+	static char user_s[MAX_STATIC_BUF];
363
+	str user = {user_s,0};
364
+	str script = {0,0};
365
+
366
+	/* check the name of the response file */
367
+	if (response_file==0) {
368
+		LOG(L_ERR,"ERROR:cpl-c:cpl_get: no reply file received from "
369
+			"FIFO command\n");
297 370
 		goto error;
371
+	}
372
+
373
+	/* first line must be the username */
374
+	if (read_line( user.s, MAX_STATIC_BUF-1 , fifo_stream, &user.len )!=1 ||
375
+	user.len<=0) {
376
+		LOG(L_ERR,"ERROR:cpl-c:cpl_get: unable to read username from "
377
+			"FIFO command\n");
378
+		goto error;
379
+	}
380
+	DBG("DEBUG:cpl-c:cpl_get: user=%.*s\n",user.len,user.s);
381
+
382
+	/* get the script for this user */
383
+	if (get_user_script( db_hdl, &user, &script, "cpl_xml")==-1)
384
+		goto error;
385
+
386
+	/* write the response into response file - even if script is null */
387
+	write_to_file( response_file, &script, !(script.len==0) );
388
+
389
+	if (script.s) shm_free( script.s );
298 390
 
299 391
 	return 1;
300 392
 error:
301 393
 	return -1;
302 394
 }
303 395
 
396
+
397
+
304 398
 #undef MAX_STATIC_BUF
305 399
 
... ...
@@ -36,6 +36,7 @@
36 36
 
37 37
 int cpl_load( FILE *fifo_stream, char *response_file );
38 38
 int cpl_remove( FILE *fifo_stream, char *response_file );
39
+int cpl_get( FILE *fifo_stream, char *response_file );
39 40
 
40 41
 #endif
41 42
 
... ...
@@ -1445,10 +1445,15 @@ error:
1445 1445
 }
1446 1446
 
1447 1447
 
1448
-#define BAD_XML      "CPL script is not a valid XML document"
1449
-#define BAD_XML_LEN  (sizeof(BAD_XML)-1)
1450
-#define BAD_CPL      "CPL script doesn't respect CPL grammar"
1451
-#define BAD_CPL_LEN  (sizeof(BAD_CPL)-1)
1448
+
1449
+#define BAD_XML       "CPL script is not a valid XML document"
1450
+#define BAD_XML_LEN   (sizeof(BAD_XML)-1)
1451
+#define BAD_CPL       "CPL script doesn't respect CPL grammar"
1452
+#define BAD_CPL_LEN   (sizeof(BAD_CPL)-1)
1453
+#define NULL_CPL      "Empty CPL script"
1454
+#define NULL_CPL_LEN  (sizeof(NULL_CPL)-1)
1455
+#define ENC_ERR       "Encoding of the CPL script failed"
1456
+#define ENC_ERR_LEN   (sizeof(ENC_ERR)-1)
1452 1457
 
1453 1458
 int encodeCPL( str *xml, str *bin, str *log)
1454 1459
 {
... ...
@@ -1467,27 +1472,28 @@ int encodeCPL( str *xml, str *bin, str *log)
1467 1472
 	doc = xmlParseDoc( (unsigned char*)xml->s );
1468 1473
 	if (!doc) {
1469 1474
 		append_log( 1, ERR BAD_XML LF, ERR_LEN+BAD_XML_LEN+LF_LEN);
1470
-		LOG(L_ERR,"ERROR:cpl:encodeCPL:CPL script not parsed successfully\n");
1475
+		LOG(L_ERR,"ERROR:cpl:encodeCPL:" BAD_XML "\n");
1471 1476
 		goto error;
1472 1477
 	}
1473 1478
 
1474 1479
 	/* check the xml against dtd */
1475 1480
 	if (xmlValidateDtd(&cvp, doc, dtd)!=1) {
1476 1481
 		append_log( 1, ERR BAD_CPL LF, ERR_LEN+BAD_CPL_LEN+LF_LEN);
1477
-		LOG(L_ERR,"ERROR:cpl-c:encodeCPL: CPL script do not matche DTD\n");
1482
+		LOG(L_ERR,"ERROR:cpl-c:encodeCPL: " BAD_CPL "\n");
1478 1483
 		goto error;
1479 1484
 	}
1480 1485
 
1481 1486
 	cur = xmlDocGetRootElement(doc);
1482 1487
 	if (!cur) {
1483
-		LOG(L_ERR,"ERROR:cpl-c:encodeCPL: empty CPL script!\n");
1488
+		append_log( 1, ERR NULL_CPL LF, ERR_LEN+NULL_CPL_LEN+LF_LEN);
1489
+		LOG(L_ERR,"ERROR:cpl-c:encodeCPL: " NULL_CPL "\n");
1484 1490
 		goto error;
1485 1491
 	}
1486 1492
 
1487 1493
 	bin->len = encode_node( cur, buf, buf+ENCONDING_BUFFER_SIZE);
1488 1494
 	if (bin->len<0) {
1489
-		LOG(L_ERR,"ERROR:cpl-c:encodeCPL: zero lenght return by encripting"
1490
-			" function\n");
1495
+		append_log( 1, ERR ENC_ERR LF, ERR_LEN+ENC_ERR_LEN+LF_LEN);
1496
+		LOG(L_ERR,"ERROR:cpl-c:encodeCPL: " ENC_ERR "\n");
1491 1497
 		goto error;
1492 1498
 	}
1493 1499
 
... ...
@@ -1496,7 +1502,6 @@ int encodeCPL( str *xml, str *bin, str *log)
1496 1502
 	/* compile the log buffer */
1497 1503
 	compile_logs( log );
1498 1504
 	bin->s = buf;
1499
-	/*write_to_file("cpl.dat", bin);  only for debugging */
1500 1505
 	return 1;
1501 1506
 error:
1502 1507
 	if (doc) xmlFreeDoc(doc);
... ...
@@ -1507,7 +1512,7 @@ error:
1507 1512
 }
1508 1513
 
1509 1514
 
1510
-
1515
+#if 0
1511 1516
 static void err_print(void *ctx, const char *msg, ...)
1512 1517
 {
1513 1518
 	va_list ap;
... ...
@@ -1522,7 +1527,7 @@ static void err_print(void *ctx, const char *msg, ...)
1522 1527
 	//append_log( 2, ERR, ERR_LEN, msg, strlen(msg) );
1523 1528
 	va_end(ap);
1524 1529
 }
1525
-
1530
+#endif
1526 1531
 
1527 1532
 
1528 1533
 /* loads and parse the dtd file; a validating context is created */