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