Mon Mar 20 08:25:43 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

image.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Image Management
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 /* We need to have some sort of read-only lock */
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             /* Reset file pointer */
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 

Generated on Mon Mar 20 08:25:43 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1