00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
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