Asterisk - The Open Source Telephony Project GIT-master-f36a736
image.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 1999 - 2006, Digium, Inc.
5 *
6 * Mark Spencer <markster@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*! \file
20 *
21 * \brief Image Management
22 *
23 * \author Mark Spencer <markster@digium.com>
24 */
25
26/*** MODULEINFO
27 <support_level>core</support_level>
28 ***/
29
30#include "asterisk.h"
31
32#include <sys/time.h>
33#include <sys/stat.h>
34#include <signal.h>
35
36#include "asterisk/paths.h" /* use ast_config_AST_DATA_DIR */
37#include "asterisk/sched.h"
38#include "asterisk/channel.h"
39#include "asterisk/file.h"
40#include "asterisk/image.h"
41#include "asterisk/translate.h"
42#include "asterisk/cli.h"
43#include "asterisk/lock.h"
44
45/* XXX Why don't we just use the formats struct for this? */
47
49{
53 ast_verb(5, "Registered format '%s' (%s)\n", img->name, img->desc);
54 return 0;
55}
56
58{
60 img = AST_RWLIST_REMOVE(&imagers, img, list);
62
63 if (img)
64 ast_verb(5, "Unregistered format '%s' (%s)\n", img->name, img->desc);
65}
66
68{
69 if (!chan || !ast_channel_tech(chan))
70 return 0;
71 if (!ast_channel_tech(chan)->send_image)
72 return 0;
73 return 1;
74}
75
76static int file_exists(char *filename)
77{
78 int res;
79 struct stat st;
80 res = stat(filename, &st);
81 if (!res)
82 return st.st_size;
83 return 0;
84}
85
86static void make_filename(char *buf, int len, const char *filename, const char *preflang, char *ext)
87{
88 if (filename[0] == '/') {
89 if (!ast_strlen_zero(preflang))
90 snprintf(buf, len, "%s-%s.%s", filename, preflang, ext);
91 else
92 snprintf(buf, len, "%s.%s", filename, ext);
93 } else {
94 if (!ast_strlen_zero(preflang))
95 snprintf(buf, len, "%s/%s/%s-%s.%s", ast_config_AST_DATA_DIR, "images", filename, preflang, ext);
96 else
97 snprintf(buf, len, "%s/%s/%s.%s", ast_config_AST_DATA_DIR, "images", filename, ext);
98 }
99}
100
101struct ast_frame *ast_read_image(const char *filename, const char *preflang, struct ast_format *format)
102{
103 struct ast_imager *i;
104 char buf[256];
105 char tmp[80];
106 char *e;
107 struct ast_imager *found = NULL;
108 int fd;
109 int len=0;
110 struct ast_frame *f = NULL;
111
113 AST_RWLIST_TRAVERSE(&imagers, i, list) {
114 /* if NULL image format, just pick the first one, otherwise match it. */
115 if (!format || (ast_format_cmp(i->format, format) == AST_FORMAT_CMP_EQUAL)) {
116 char *stringp=NULL;
117 ast_copy_string(tmp, i->exts, sizeof(tmp));
118 stringp = tmp;
119 e = strsep(&stringp, "|");
120 while (e) {
121 make_filename(buf, sizeof(buf), filename, preflang, e);
122 if ((len = file_exists(buf))) {
123 found = i;
124 break;
125 }
126 make_filename(buf, sizeof(buf), filename, NULL, e);
127 if ((len = file_exists(buf))) {
128 found = i;
129 break;
130 }
131 e = strsep(&stringp, "|");
132 }
133 }
134 if (found)
135 break;
136 }
137
138 if (found) {
139 fd = open(buf, O_RDONLY);
140 if (fd > -1) {
141 if (!found->identify || found->identify(fd)) {
142 /* Reset file pointer */
143 lseek(fd, 0, SEEK_SET);
144 f = found->read_image(fd, len);
145 } else
146 ast_log(LOG_WARNING, "%s does not appear to be a %s file\n", buf, found->name);
147 close(fd);
148 } else
149 ast_log(LOG_WARNING, "Unable to open '%s': %s\n", buf, strerror(errno));
150 } else
151 ast_log(LOG_WARNING, "Image file '%s' not found\n", filename);
152
154
155 return f;
156}
157
158int ast_send_image(struct ast_channel *chan, const char *filename)
159{
160 struct ast_frame *f;
161 int res = -1;
162 if (ast_channel_tech(chan)->send_image) {
163 f = ast_read_image(filename, ast_channel_language(chan), NULL);
164 if (f) {
165 res = ast_channel_tech(chan)->send_image(chan, f);
166 ast_frfree(f);
167 }
168 }
169 return res;
170}
171
172static char *handle_core_show_image_formats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
173{
174#define FORMAT "%10s %10s %50s %10s\n"
175#define FORMAT2 "%10s %10s %50s %10s\n"
176 struct ast_imager *i;
177 int count_fmt = 0;
178
179 switch (cmd) {
180 case CLI_INIT:
181 e->command = "core show image formats";
182 e->usage =
183 "Usage: core show image formats\n"
184 " Displays currently registered image formats (if any).\n";
185 return NULL;
186 case CLI_GENERATE:
187 return NULL;
188 }
189 if (a->argc != 4)
190 return CLI_SHOWUSAGE;
191 ast_cli(a->fd, FORMAT, "Name", "Extensions", "Description", "Format");
192 ast_cli(a->fd, FORMAT, "----", "----------", "-----------", "------");
194 AST_RWLIST_TRAVERSE(&imagers, i, list) {
195 ast_cli(a->fd, FORMAT2, i->name, i->exts, i->desc, ast_format_get_name(i->format));
196 count_fmt++;
197 }
199 ast_cli(a->fd, "\n%d image format%s registered.\n", count_fmt, count_fmt == 1 ? "" : "s");
200 return CLI_SUCCESS;
201}
202
203static struct ast_cli_entry cli_image[] = {
204 AST_CLI_DEFINE(handle_core_show_image_formats, "Displays image formats")
205};
206
207static void image_shutdown(void)
208{
210}
211
213{
216 return 0;
217}
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ast_log
Definition: astobj2.c:42
static int tmp()
Definition: bt_open.c:389
General Asterisk PBX channel definitions.
const char * ast_channel_language(const struct ast_channel *chan)
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
Standard Command Line Interface.
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:197
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
Generic File Format Support. Should be included by clients of the file handling routines....
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
@ AST_FORMAT_CMP_EQUAL
Definition: format.h:36
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
const char * ext
Definition: http.c:150
int ast_image_register(struct ast_imager *img)
Register image format.
Definition: image.c:48
int ast_send_image(struct ast_channel *chan, const char *filename)
Sends an image.
Definition: image.c:158
static char * handle_core_show_image_formats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: image.c:172
int ast_image_init(void)
Initialize image stuff Initializes all the various image stuff. Basically just registers the cli stuf...
Definition: image.c:212
static int file_exists(char *filename)
Definition: image.c:76
int ast_supports_images(struct ast_channel *chan)
Check for image support on a channel.
Definition: image.c:67
void ast_image_unregister(struct ast_imager *img)
Unregister an image format.
Definition: image.c:57
static void make_filename(char *buf, int len, const char *filename, const char *preflang, char *ext)
Definition: image.c:86
#define FORMAT
#define FORMAT2
struct ast_frame * ast_read_image(const char *filename, const char *preflang, struct ast_format *format)
Make an image.
Definition: image.c:101
static void image_shutdown(void)
Definition: image.c:207
static struct ast_cli_entry cli_image[]
Definition: image.c:203
General Asterisk channel definitions for image handling.
char * strsep(char **str, const char *delims)
#define ast_frfree(fr)
#define ast_verb(level,...)
#define LOG_WARNING
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized.
Definition: linkedlists.h:333
#define AST_RWLIST_REMOVE
Definition: linkedlists.h:885
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:718
Asterisk locking-related definitions:
int errno
Asterisk file paths, configured in asterisk.conf.
const char * ast_config_AST_DATA_DIR
Definition: options.c:158
#define NULL
Definition: resample.c:96
Scheduler Routines (derived from cheops)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int(*const send_image)(struct ast_channel *chan, struct ast_frame *frame)
Display or send an image.
Definition: channel.h:779
Main Channel structure associated with a channel.
descriptor for a cli entry.
Definition: cli.h:171
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
Definition of a media format.
Definition: format.c:43
Data structure associated with a single frame of data.
structure associated with registering an image format
Definition: image.h:27
char * desc
Definition: image.h:29
char * name
Definition: image.h:28
int(* identify)(int fd)
Definition: image.h:33
struct ast_format * format
Definition: image.h:31
struct ast_frame *(* read_image)(int fd, int len)
Definition: image.h:32
char * exts
Definition: image.h:30
Definition: image.c:46
static struct test_val a
Support for translation of data formats. translate.c.
#define ARRAY_LEN(a)
Definition: utils.h:666