Main Page | Alphabetical List | Data Structures | Directories | 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 <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 /* 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 Nov 25 19:09:37 2006 for Asterisk by  doxygen 1.4.2