Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

image.c

Go to the documentation of this file.
00001 /* 00002 * Asterisk -- A telephony toolkit for Linux. 00003 * 00004 * Channel Management 00005 * 00006 * Copyright (C) 1999, Mark Spencer 00007 * 00008 * Mark Spencer <markster@linux-support.net> 00009 * 00010 * This program is free software, distributed under the terms of 00011 * the GNU General Public License 00012 */ 00013 00014 #include <stdio.h> 00015 #include <stdlib.h> 00016 #include <pthread.h> 00017 #include <string.h> 00018 #include <sys/time.h> 00019 #include <sys/stat.h> 00020 #include <signal.h> 00021 #include <errno.h> 00022 #include <unistd.h> 00023 #include <asterisk/sched.h> 00024 #include <asterisk/options.h> 00025 #include <asterisk/channel.h> 00026 #include <asterisk/channel_pvt.h> 00027 #include <asterisk/logger.h> 00028 #include <asterisk/file.h> 00029 #include <asterisk/image.h> 00030 #include <asterisk/translate.h> 00031 #include <asterisk/cli.h> 00032 #include "asterisk.h" 00033 #include "astconf.h" 00034 00035 static struct ast_imager *list; 00036 AST_MUTEX_DEFINE_STATIC(listlock); 00037 00038 int ast_image_register(struct ast_imager *img) 00039 { 00040 if (option_verbose > 1) 00041 ast_verbose(VERBOSE_PREFIX_2 "Registered format '%s' (%s)\n", img->name, img->desc); 00042 ast_mutex_lock(&listlock); 00043 img->next = list; 00044 list = img; 00045 ast_mutex_unlock(&listlock); 00046 return 0; 00047 } 00048 00049 void ast_image_unregister(struct ast_imager *img) 00050 { 00051 struct ast_imager *i, *prev = NULL; 00052 ast_mutex_lock(&listlock); 00053 i = list; 00054 while(i) { 00055 if (i == img) { 00056 if (prev) 00057 prev->next = i->next; 00058 else 00059 list = i->next; 00060 break; 00061 } 00062 prev = i; 00063 i = i->next; 00064 } 00065 ast_mutex_unlock(&listlock); 00066 if (i && (option_verbose > 1)) 00067 ast_verbose(VERBOSE_PREFIX_2 "Unregistered format '%s' (%s)\n", img->name, img->desc); 00068 } 00069 00070 int ast_supports_images(struct ast_channel *chan) 00071 { 00072 if (!chan || !chan->pvt) 00073 return 0; 00074 if (!chan->pvt->send_image) 00075 return 0; 00076 return 1; 00077 } 00078 00079 static int file_exists(char *filename) 00080 { 00081 int res; 00082 struct stat st; 00083 res = stat(filename, &st); 00084 if (!res) 00085 return st.st_size; 00086 return 0; 00087 } 00088 00089 static void make_filename(char *buf, int len, char *filename, char *preflang, char *ext) 00090 { 00091 if (filename[0] == '/') { 00092 if (preflang && strlen(preflang)) 00093 snprintf(buf, len, "%s-%s.%s", filename, preflang, ext); 00094 else 00095 snprintf(buf, len, "%s.%s", filename, ext); 00096 } else { 00097 if (preflang && strlen(preflang)) 00098 snprintf(buf, len, "%s/%s/%s-%s.%s", ast_config_AST_VAR_DIR, "images", filename, preflang, ext); 00099 else 00100 snprintf(buf, len, "%s/%s/%s.%s", ast_config_AST_VAR_DIR, "images", filename, ext); 00101 } 00102 } 00103 00104 struct ast_frame *ast_read_image(char *filename, char *preflang, int format) 00105 { 00106 struct ast_imager *i; 00107 char buf[256]; 00108 char tmp[80]; 00109 char *e; 00110 struct ast_imager *found = NULL; 00111 int fd; 00112 int len=0; 00113 struct ast_frame *f = NULL; 00114 #if 0 /* We need to have some sort of read-only lock */ 00115 ast_mutex_lock(&listlock); 00116 #endif 00117 i = list; 00118 while(!found && i) { 00119 if (i->format & format) { 00120 char *stringp=NULL; 00121 strncpy(tmp, i->exts, sizeof(tmp)-1); 00122 stringp=tmp; 00123 e = strsep(&stringp, "|"); 00124 while(e) { 00125 make_filename(buf, sizeof(buf), filename, preflang, e); 00126 if ((len = file_exists(buf))) { 00127 found = i; 00128 break; 00129 } 00130 make_filename(buf, sizeof(buf), filename, NULL, e); 00131 if ((len = file_exists(buf))) { 00132 found = i; 00133 break; 00134 } 00135 e = strsep(&stringp, "|"); 00136 } 00137 } 00138 i = i->next; 00139 } 00140 if (found) { 00141 fd = open(buf, O_RDONLY); 00142 if (fd > -1) { 00143 if (!found->identify || found->identify(fd)) { 00144 /* Reset file pointer */ 00145 lseek(fd, 0, SEEK_SET); 00146 f = found->read_image(fd,len); 00147 } else 00148 ast_log(LOG_WARNING, "%s does not appear to be a %s file\n", buf, i->name); 00149 close(fd); 00150 } else 00151 ast_log(LOG_WARNING, "Unable to open '%s': %s\n", buf, strerror(errno)); 00152 } else 00153 ast_log(LOG_WARNING, "Image file '%s' not found\n", filename); 00154 #if 0 00155 ast_mutex_unlock(&listlock); 00156 #endif 00157 return f; 00158 } 00159 00160 00161 int ast_send_image(struct ast_channel *chan, char *filename) 00162 { 00163 struct ast_frame *f; 00164 int res = -1; 00165 if (chan->pvt->send_image) { 00166 f = ast_read_image(filename, chan->language, -1); 00167 if (f) { 00168 res = chan->pvt->send_image(chan, f); 00169 ast_frfree(f); 00170 } 00171 } 00172 return res; 00173 } 00174 00175 static int show_image_formats(int fd, int argc, char *argv[]) 00176 { 00177 #define FORMAT "%10s %10s %50s %10s\n" 00178 #define FORMAT2 "%10s %10s %50s %10s\n" 00179 struct ast_imager *i; 00180 if (argc != 3) 00181 return RESULT_SHOWUSAGE; 00182 ast_cli(fd, FORMAT, "Name", "Extensions", "Description", "Format"); 00183 i = list; 00184 while(i) { 00185 ast_cli(fd, FORMAT2, i->name, i->exts, i->desc, ast_getformatname(i->format)); 00186 i = i->next; 00187 }; 00188 return RESULT_SUCCESS; 00189 } 00190 00191 struct ast_cli_entry show_images = 00192 { 00193 { "show", "image", "formats" }, 00194 show_image_formats, 00195 "Displays image formats", 00196 "Usage: show image formats\n" 00197 " displays currently registered image formats (if any)\n" 00198 }; 00199 00200 00201 int ast_image_init(void) 00202 { 00203 ast_cli_register(&show_images); 00204 return 0; 00205 } 00206

Generated on Sat Jun 12 16:40:58 2004 for Asterisk by doxygen 1.3.7