| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * Asterisk -- An open source telephony toolkit. | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-01-21 07:06:25 +00:00
										 |  |  |  * Copyright (C) 2004 - 2005, Andy Powell  | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Updated by Mark Spencer <markster@digium.com> | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * See http://www.asterisk.org for more information about
 | 
					
						
							|  |  |  |  * the Asterisk project. Please do not directly contact | 
					
						
							|  |  |  |  * any of the maintainers of this project for assistance; | 
					
						
							|  |  |  |  * the project provides a web site, mailing lists and IRC | 
					
						
							|  |  |  |  * channels for your use. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software, distributed under the terms of | 
					
						
							|  |  |  |  * the GNU General Public License Version 2. See the LICENSE file | 
					
						
							|  |  |  |  * at the top of the source tree. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | /*! \file
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  |  * \brief A simple math application | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  *  | 
					
						
							| 
									
										
										
										
											2005-11-06 15:09:47 +00:00
										 |  |  |  * \ingroup applications | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-06 22:39:32 +00:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <errno.h>
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <sys/time.h>
 | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							|  |  |  | #include <sys/types.h>
 | 
					
						
							|  |  |  | #include <time.h>
 | 
					
						
							|  |  |  | #include <dirent.h>
 | 
					
						
							|  |  |  | #include <ctype.h>
 | 
					
						
							|  |  |  | #include <sys/file.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "asterisk.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-21 06:02:45 +00:00
										 |  |  | #include "asterisk/lock.h"
 | 
					
						
							|  |  |  | #include "asterisk/file.h"
 | 
					
						
							|  |  |  | #include "asterisk/logger.h"
 | 
					
						
							|  |  |  | #include "asterisk/channel.h"
 | 
					
						
							|  |  |  | #include "asterisk/pbx.h"
 | 
					
						
							|  |  |  | #include "asterisk/options.h"
 | 
					
						
							|  |  |  | #include "asterisk/config.h"
 | 
					
						
							|  |  |  | #include "asterisk/say.h"
 | 
					
						
							|  |  |  | #include "asterisk/module.h"
 | 
					
						
							|  |  |  | #include "asterisk/app.h"
 | 
					
						
							|  |  |  | #include "asterisk/manager.h"
 | 
					
						
							|  |  |  | #include "asterisk/localtime.h"
 | 
					
						
							|  |  |  | #include "asterisk/cli.h"
 | 
					
						
							|  |  |  | #include "asterisk/utils.h"
 | 
					
						
							|  |  |  | #include "asterisk/module.h"
 | 
					
						
							|  |  |  | #include "asterisk/translate.h"
 | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-02-16 01:05:08 +00:00
										 |  |  | static char *tdesc = "Basic Math Functions"; | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static char *app_math = "Math"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *math_synopsis = "Performs Mathematical Functions"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *math_descrip = | 
					
						
							|  |  |  | "Math(returnvar,<number1><op><number 2>\n\n" | 
					
						
							|  |  |  | "Perform floating point calculation on number 1 to number 2 and \n" | 
					
						
							|  |  |  | "store the result in returnvar.  Valid ops are: \n" | 
					
						
							|  |  |  | "    +,-,/,*,%,<,>,>=,<=,==\n" | 
					
						
							| 
									
										
										
										
											2005-11-07 22:01:22 +00:00
										 |  |  | "and behave as their C equivalents.\n"; | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define ADDFUNCTION 0
 | 
					
						
							|  |  |  | #define DIVIDEFUNCTION 1
 | 
					
						
							|  |  |  | #define MULTIPLYFUNCTION 2
 | 
					
						
							|  |  |  | #define SUBTRACTFUNCTION 3
 | 
					
						
							|  |  |  | #define MODULUSFUNCTION 4
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define GTFUNCTION 5
 | 
					
						
							|  |  |  | #define LTFUNCTION 6
 | 
					
						
							|  |  |  | #define GTEFUNCTION 7
 | 
					
						
							|  |  |  | #define LTEFUNCTION 8
 | 
					
						
							|  |  |  | #define EQFUNCTION 9
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | STANDARD_LOCAL_USER; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LOCAL_USER_DECL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | static int math_exec(struct ast_channel *chan, void *data)  | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float fnum1; | 
					
						
							|  |  |  | 	float fnum2; | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | 	float ftmp = 0; | 
					
						
							|  |  |  | 	char *op; | 
					
						
							|  |  |  | 	int iaction=-1; | 
					
						
							| 
									
										
										
										
											2005-06-09 22:59:08 +00:00
										 |  |  | 	static int deprecation_warning = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | 	/* dunno, big calulations :D */ | 
					
						
							|  |  |  | 	char user_result[30]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 	char *s; | 
					
						
							|  |  |  | 	char *mvar, *mvalue1, *mvalue2=NULL; | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 	struct localuser *u; | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-12 16:43:37 +00:00
										 |  |  | 	if (!deprecation_warning) { | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Math() is deprecated, please use Set(var=${MATH(...)} instead.\n"); | 
					
						
							|  |  |  | 		deprecation_warning = 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-26 19:48:14 +00:00
										 |  |  | 	if (ast_strlen_zero(data)) { | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 		ast_log(LOG_WARNING, "No parameters passed. !\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 	LOCAL_USER_ADD(u); | 
					
						
							| 
									
										
										
										
											2005-10-19 18:19:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	s = ast_strdupa(data); | 
					
						
							|  |  |  | 	if (!s) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Out of memory\n"); | 
					
						
							|  |  |  | 		LOCAL_USER_REMOVE(u); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	mvar = strsep(&s, "|"); | 
					
						
							|  |  |  | 	mvalue1 = strsep(&s, "|"); | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if ((op = strchr(mvalue1, '+'))) { | 
					
						
							|  |  |  | 		iaction = ADDFUNCTION; | 
					
						
							|  |  |  | 		*op = '\0'; | 
					
						
							|  |  |  | 	} else if ((op = strchr(mvalue1, '-'))) { | 
					
						
							|  |  |  | 		iaction = SUBTRACTFUNCTION; | 
					
						
							|  |  |  | 		*op = '\0'; | 
					
						
							|  |  |  | 	} else if ((op = strchr(mvalue1, '*'))) { | 
					
						
							|  |  |  | 		iaction = MULTIPLYFUNCTION; | 
					
						
							|  |  |  | 		*op = '\0'; | 
					
						
							|  |  |  | 	} else if ((op = strchr(mvalue1, '/'))) { | 
					
						
							|  |  |  | 		iaction = DIVIDEFUNCTION; | 
					
						
							|  |  |  | 		*op = '\0'; | 
					
						
							|  |  |  | 	} else if ((op = strchr(mvalue1, '>'))) { | 
					
						
							|  |  |  | 		iaction = GTFUNCTION; | 
					
						
							|  |  |  | 		*op = '\0'; | 
					
						
							|  |  |  | 		if (*(op+1) == '=') { | 
					
						
							|  |  |  | 			op++; | 
					
						
							|  |  |  | 			*op = '\0'; | 
					
						
							|  |  |  | 			iaction = GTEFUNCTION; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else if ((op = strchr(mvalue1, '<'))) { | 
					
						
							|  |  |  | 		iaction = LTFUNCTION; | 
					
						
							|  |  |  | 		*op = '\0'; | 
					
						
							|  |  |  | 		if (*(op+1) == '=') { | 
					
						
							|  |  |  | 			op++; | 
					
						
							|  |  |  | 			*op = '\0'; | 
					
						
							|  |  |  | 			iaction = LTEFUNCTION; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else if ((op = strchr(mvalue1, '='))) { | 
					
						
							|  |  |  | 		iaction = GTFUNCTION; | 
					
						
							|  |  |  | 		*op = '\0'; | 
					
						
							|  |  |  | 		if (*(op+1) == '=') { | 
					
						
							|  |  |  | 			op++; | 
					
						
							|  |  |  | 			*op = '\0'; | 
					
						
							|  |  |  | 			iaction = EQFUNCTION; | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 			op = NULL; | 
					
						
							|  |  |  | 	}  | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (op)  | 
					
						
							|  |  |  | 		mvalue2 = op + 1; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	if (!mvar || !mvalue1 || !mvalue2) { | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 		ast_log(LOG_WARNING, "Supply all the parameters - just this once, please\n"); | 
					
						
							|  |  |  | 		LOCAL_USER_REMOVE(u); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!strcmp(mvar,"")) { | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 		ast_log(LOG_WARNING, "No return variable set.\n"); | 
					
						
							|  |  |  | 		LOCAL_USER_REMOVE(u); | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 	if (sscanf(mvalue1, "%f", &fnum1) != 1) { | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue1); | 
					
						
							|  |  |  | 		LOCAL_USER_REMOVE(u); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 	if (sscanf(mvalue2, "%f", &fnum2) != 1) { | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue2); | 
					
						
							|  |  |  | 		LOCAL_USER_REMOVE(u); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 	switch (iaction) { | 
					
						
							|  |  |  | 	case ADDFUNCTION : | 
					
						
							|  |  |  | 		ftmp = fnum1 + fnum2; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case DIVIDEFUNCTION : | 
					
						
							|  |  |  | 		if (fnum2 <=0) | 
					
						
							|  |  |  | 			ftmp = 0; /* can't do a divide by 0 */ | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			ftmp = (fnum1 / fnum2); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case MULTIPLYFUNCTION : | 
					
						
							|  |  |  | 		ftmp = (fnum1 * fnum2); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SUBTRACTFUNCTION : | 
					
						
							| 
									
										
										
										
											2004-11-14 00:24:35 +00:00
										 |  |  | 		ftmp = (fnum1 - fnum2); | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case MODULUSFUNCTION : { | 
					
						
							|  |  |  | 		int inum1 = fnum1; | 
					
						
							|  |  |  | 		int inum2 = fnum2; | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 		ftmp = (inum1 % inum2); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	case GTFUNCTION : | 
					
						
							|  |  |  | 		if (fnum1 > fnum2) | 
					
						
							| 
									
										
										
										
											2005-07-10 23:12:25 +00:00
										 |  |  | 			strcpy(user_result, "TRUE"); | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2005-07-10 23:12:25 +00:00
										 |  |  | 			strcpy(user_result, "FALSE"); | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case LTFUNCTION : | 
					
						
							|  |  |  | 		if (fnum1 < fnum2) | 
					
						
							| 
									
										
										
										
											2005-07-10 23:12:25 +00:00
										 |  |  | 			strcpy(user_result, "TRUE"); | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2005-07-10 23:12:25 +00:00
										 |  |  | 			strcpy(user_result, "FALSE"); | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case GTEFUNCTION : | 
					
						
							|  |  |  | 		if (fnum1 >= fnum2) | 
					
						
							| 
									
										
										
										
											2005-07-10 23:12:25 +00:00
										 |  |  | 			strcpy(user_result, "TRUE"); | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2005-07-10 23:12:25 +00:00
										 |  |  | 			strcpy(user_result, "FALSE"); | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case LTEFUNCTION : | 
					
						
							|  |  |  | 		if (fnum1 <= fnum2) | 
					
						
							| 
									
										
										
										
											2005-07-10 23:12:25 +00:00
										 |  |  | 			strcpy(user_result, "TRUE"); | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2005-07-10 23:12:25 +00:00
										 |  |  | 			strcpy(user_result, "FALSE"); | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 		break;					 | 
					
						
							|  |  |  | 	case EQFUNCTION : | 
					
						
							|  |  |  | 		if (fnum1 == fnum2) | 
					
						
							| 
									
										
										
										
											2005-07-10 23:12:25 +00:00
										 |  |  | 			strcpy(user_result, "TRUE"); | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2005-07-10 23:12:25 +00:00
										 |  |  | 			strcpy(user_result, "FALSE"); | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	default : | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Something happened that neither of us should be proud of %d\n", iaction); | 
					
						
							|  |  |  | 		LOCAL_USER_REMOVE(u); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (iaction < GTFUNCTION || iaction > EQFUNCTION)  | 
					
						
							|  |  |  | 		snprintf(user_result,sizeof(user_result),"%f",ftmp); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	pbx_builtin_setvar_helper(chan, mvar, user_result);	 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	LOCAL_USER_REMOVE(u); | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int unload_module(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 	int res; | 
					
						
							| 
									
										
										
										
											2005-10-18 22:52:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	res = ast_unregister_application(app_math); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 15:59:52 +00:00
										 |  |  | 	STANDARD_HANGUP_LOCALUSERS; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return res; | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int load_module(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2005-10-18 22:52:21 +00:00
										 |  |  | 	return ast_register_application(app_math, math_exec, math_synopsis, math_descrip); | 
					
						
							| 
									
										
										
										
											2004-10-03 14:19:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char *description(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return tdesc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int usecount(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int res; | 
					
						
							|  |  |  | 	STANDARD_USECOUNT(res); | 
					
						
							|  |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char *key() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ASTERISK_GPL_KEY; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Fading everything to black and blue... */ |