00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <string.h>
00017 #include <sys/time.h>
00018 #include <sys/stat.h>
00019 #include <signal.h>
00020 #include <errno.h>
00021 #include <unistd.h>
00022 #include <asterisk/sched.h>
00023 #include <asterisk/options.h>
00024 #include <asterisk/channel.h>
00025 #include <asterisk/channel_pvt.h>
00026 #include <asterisk/logger.h>
00027 #include <asterisk/file.h>
00028 #include <asterisk/image.h>
00029 #include <asterisk/translate.h>
00030 #include <asterisk/cli.h>
00031 #include <asterisk/lock.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_DATA_DIR, "images", filename, preflang, ext);
00099 else
00100 snprintf(buf, len, "%s/%s/%s.%s", ast_config_AST_DATA_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
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
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