| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * Asterisk -- An open source telephony toolkit. | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2006-01-03 22:16:23 +00:00
										 |  |  |  * Copyright (C) 1999 - 2006, Digium, Inc. | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Mark Spencer <markster@digium.com> | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											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. | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This program is free software, distributed under the terms of | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * 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 Image Management | 
					
						
							| 
									
										
										
										
											2005-12-30 21:18:06 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * \author Mark Spencer <markster@digium.com>  | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-07 18:54:56 +00:00
										 |  |  | #include "asterisk.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | #include <sys/time.h>
 | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							|  |  |  | #include <signal.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-22 13:11:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-20 23:16:15 +00:00
										 |  |  | #include "asterisk/paths.h"	/* use ast_config_AST_DATA_DIR */
 | 
					
						
							| 
									
										
										
										
											2005-04-21 06:02:45 +00:00
										 |  |  | #include "asterisk/sched.h"
 | 
					
						
							|  |  |  | #include "asterisk/channel.h"
 | 
					
						
							|  |  |  | #include "asterisk/file.h"
 | 
					
						
							|  |  |  | #include "asterisk/image.h"
 | 
					
						
							|  |  |  | #include "asterisk/translate.h"
 | 
					
						
							|  |  |  | #include "asterisk/cli.h"
 | 
					
						
							|  |  |  | #include "asterisk/lock.h"
 | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-18 19:54:18 +00:00
										 |  |  | /* XXX Why don't we just use the formats struct for this? */ | 
					
						
							| 
									
										
										
										
											2007-01-26 22:55:06 +00:00
										 |  |  | static AST_RWLIST_HEAD_STATIC(imagers, ast_imager); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int ast_image_register(struct ast_imager *img) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-01-26 22:55:06 +00:00
										 |  |  | 	AST_RWLIST_WRLOCK(&imagers); | 
					
						
							|  |  |  | 	AST_RWLIST_INSERT_HEAD(&imagers, img, list); | 
					
						
							|  |  |  | 	AST_RWLIST_UNLOCK(&imagers); | 
					
						
							| 
									
										
										
										
											2007-11-14 00:33:52 +00:00
										 |  |  | 	ast_verb(2, "Registered format '%s' (%s)\n", img->name, img->desc); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ast_image_unregister(struct ast_imager *img) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-01-26 22:55:06 +00:00
										 |  |  | 	AST_RWLIST_WRLOCK(&imagers); | 
					
						
							| 
									
										
										
										
											2007-11-14 00:33:52 +00:00
										 |  |  | 	img = AST_RWLIST_REMOVE(&imagers, img, list); | 
					
						
							| 
									
										
										
										
											2007-01-26 22:55:06 +00:00
										 |  |  | 	AST_RWLIST_UNLOCK(&imagers); | 
					
						
							| 
									
										
										
										
											2007-11-14 00:33:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (img) | 
					
						
							| 
									
										
										
										
											2007-07-26 15:49:18 +00:00
										 |  |  | 		ast_verb(2, "Unregistered format '%s' (%s)\n", img->name, img->desc); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int ast_supports_images(struct ast_channel *chan) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2005-03-04 06:47:24 +00:00
										 |  |  | 	if (!chan || !chan->tech) | 
					
						
							| 
									
										
										
										
											2002-01-23 20:56:52 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2005-03-04 06:47:24 +00:00
										 |  |  | 	if (!chan->tech->send_image) | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int file_exists(char *filename) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int res; | 
					
						
							|  |  |  | 	struct stat st; | 
					
						
							|  |  |  | 	res = stat(filename, &st); | 
					
						
							|  |  |  | 	if (!res) | 
					
						
							|  |  |  | 		return st.st_size; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-01 23:05:28 +00:00
										 |  |  | static void make_filename(char *buf, int len, char *filename, const char *preflang, char *ext) | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (filename[0] == '/') { | 
					
						
							| 
									
										
										
										
											2006-03-19 15:42:49 +00:00
										 |  |  | 		if (!ast_strlen_zero(preflang)) | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 			snprintf(buf, len, "%s-%s.%s", filename, preflang, ext); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			snprintf(buf, len, "%s.%s", filename, ext); | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2006-03-19 15:42:49 +00:00
										 |  |  | 		if (!ast_strlen_zero(preflang)) | 
					
						
							| 
									
										
										
										
											2006-04-15 22:53:53 +00:00
										 |  |  | 			snprintf(buf, len, "%s/%s/%s-%s.%s", ast_config_AST_DATA_DIR, "images", filename, preflang, ext); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2006-04-15 22:53:53 +00:00
										 |  |  | 			snprintf(buf, len, "%s/%s/%s.%s", ast_config_AST_DATA_DIR, "images", filename, ext); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-01 23:05:28 +00:00
										 |  |  | struct ast_frame *ast_read_image(char *filename, const char *preflang, int format) | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ast_imager *i; | 
					
						
							|  |  |  | 	char buf[256]; | 
					
						
							|  |  |  | 	char tmp[80]; | 
					
						
							|  |  |  | 	char *e; | 
					
						
							|  |  |  | 	struct ast_imager *found = NULL; | 
					
						
							|  |  |  | 	int fd; | 
					
						
							|  |  |  | 	int len=0; | 
					
						
							|  |  |  | 	struct ast_frame *f = NULL; | 
					
						
							| 
									
										
										
										
											2006-01-03 08:40:55 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2007-01-26 22:55:06 +00:00
										 |  |  | 	AST_RWLIST_RDLOCK(&imagers); | 
					
						
							|  |  |  | 	AST_RWLIST_TRAVERSE(&imagers, i, list) { | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 		if (i->format & format) { | 
					
						
							| 
									
										
										
										
											2003-01-30 15:03:20 +00:00
										 |  |  | 			char *stringp=NULL; | 
					
						
							| 
									
										
										
										
											2006-10-25 14:44:50 +00:00
										 |  |  | 			ast_copy_string(tmp, i->exts, sizeof(tmp)); | 
					
						
							| 
									
										
										
										
											2008-03-04 23:04:29 +00:00
										 |  |  | 			stringp = tmp; | 
					
						
							| 
									
										
										
										
											2003-01-30 15:03:20 +00:00
										 |  |  | 			e = strsep(&stringp, "|"); | 
					
						
							| 
									
										
										
										
											2007-01-23 00:11:32 +00:00
										 |  |  | 			while (e) { | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 				make_filename(buf, sizeof(buf), filename, preflang, e); | 
					
						
							|  |  |  | 				if ((len = file_exists(buf))) { | 
					
						
							|  |  |  | 					found = i; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				make_filename(buf, sizeof(buf), filename, NULL, e); | 
					
						
							|  |  |  | 				if ((len = file_exists(buf))) { | 
					
						
							|  |  |  | 					found = i; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2003-01-30 15:03:20 +00:00
										 |  |  | 				e = strsep(&stringp, "|"); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-01-03 08:40:55 +00:00
										 |  |  | 		if (found) | 
					
						
							|  |  |  | 			break;	 | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-01-03 08:40:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 	if (found) { | 
					
						
							|  |  |  | 		fd = open(buf, O_RDONLY); | 
					
						
							|  |  |  | 		if (fd > -1) { | 
					
						
							|  |  |  | 			if (!found->identify || found->identify(fd)) { | 
					
						
							|  |  |  | 				/* Reset file pointer */ | 
					
						
							|  |  |  | 				lseek(fd, 0, SEEK_SET); | 
					
						
							| 
									
										
										
										
											2008-03-04 23:04:29 +00:00
										 |  |  | 				f = found->read_image(fd, len);  | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 			} else | 
					
						
							| 
									
										
										
										
											2006-03-24 14:51:15 +00:00
										 |  |  | 				ast_log(LOG_WARNING, "%s does not appear to be a %s file\n", buf, found->name); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 			close(fd); | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to open '%s': %s\n", buf, strerror(errno)); | 
					
						
							|  |  |  | 	} else | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Image file '%s' not found\n", filename); | 
					
						
							| 
									
										
										
										
											2006-01-03 08:40:55 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2007-01-26 22:55:06 +00:00
										 |  |  | 	AST_RWLIST_UNLOCK(&imagers); | 
					
						
							| 
									
										
										
										
											2006-01-03 08:40:55 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 	return f; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int ast_send_image(struct ast_channel *chan, char *filename) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ast_frame *f; | 
					
						
							|  |  |  | 	int res = -1; | 
					
						
							| 
									
										
										
										
											2005-03-04 06:47:24 +00:00
										 |  |  | 	if (chan->tech->send_image) { | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 		f = ast_read_image(filename, chan->language, -1); | 
					
						
							|  |  |  | 		if (f) { | 
					
						
							| 
									
										
										
										
											2005-03-04 06:47:24 +00:00
										 |  |  | 			res = chan->tech->send_image(chan, f); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 			ast_frfree(f); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | static char *handle_core_show_image_formats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-18 19:54:18 +00:00
										 |  |  | #define FORMAT "%10s %10s %50s %10s\n"
 | 
					
						
							|  |  |  | #define FORMAT2 "%10s %10s %50s %10s\n"
 | 
					
						
							|  |  |  | 	struct ast_imager *i; | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 	int count_fmt = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (cmd) { | 
					
						
							|  |  |  | 	case CLI_INIT: | 
					
						
							|  |  |  | 		e->command = "core show image formats"; | 
					
						
							|  |  |  | 		e->usage = | 
					
						
							|  |  |  | 			"Usage: core show image formats\n" | 
					
						
							|  |  |  | 			"       Displays currently registered image formats (if any).\n"; | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	case CLI_GENERATE: | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (a->argc != 4) | 
					
						
							|  |  |  | 		return CLI_SHOWUSAGE; | 
					
						
							|  |  |  | 	ast_cli(a->fd, FORMAT, "Name", "Extensions", "Description", "Format"); | 
					
						
							|  |  |  | 	ast_cli(a->fd, FORMAT, "----", "----------", "-----------", "------"); | 
					
						
							| 
									
										
										
										
											2007-01-26 22:55:06 +00:00
										 |  |  | 	AST_RWLIST_RDLOCK(&imagers); | 
					
						
							|  |  |  | 	AST_RWLIST_TRAVERSE(&imagers, i, list) { | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 		ast_cli(a->fd, FORMAT2, i->name, i->exts, i->desc, ast_getformatname(i->format)); | 
					
						
							|  |  |  | 		count_fmt++; | 
					
						
							| 
									
										
										
										
											2007-01-26 22:55:06 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	AST_RWLIST_UNLOCK(&imagers); | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 	ast_cli(a->fd, "\n%d image format%s registered.\n", count_fmt, count_fmt == 1 ? "" : "s"); | 
					
						
							|  |  |  | 	return CLI_SUCCESS; | 
					
						
							| 
									
										
										
										
											2006-09-18 19:54:18 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct ast_cli_entry cli_image[] = { | 
					
						
							| 
									
										
										
										
											2007-10-22 20:05:18 +00:00
										 |  |  | 	AST_CLI_DEFINE(handle_core_show_image_formats, "Displays image formats") | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int ast_image_init(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-11-14 00:33:52 +00:00
										 |  |  | 	ast_cli_register_multiple(cli_image, ARRAY_LEN(cli_image)); | 
					
						
							| 
									
										
										
										
											2006-09-18 19:54:18 +00:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | } |