Wed Jan 8 2020 09:49:48

Asterisk developer's documentation


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 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 377881 $")
33 
34 #include <sys/time.h>
35 #include <sys/stat.h>
36 #include <signal.h>
37 
38 #include "asterisk/paths.h" /* use ast_config_AST_DATA_DIR */
39 #include "asterisk/sched.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/file.h"
42 #include "asterisk/image.h"
43 #include "asterisk/translate.h"
44 #include "asterisk/cli.h"
45 #include "asterisk/lock.h"
46 
47 /* XXX Why don't we just use the formats struct for this? */
49 
51 {
53  AST_RWLIST_INSERT_HEAD(&imagers, img, list);
55  ast_verb(2, "Registered format '%s' (%s)\n", img->name, img->desc);
56  return 0;
57 }
58 
60 {
62  img = AST_RWLIST_REMOVE(&imagers, img, list);
64 
65  if (img)
66  ast_verb(2, "Unregistered format '%s' (%s)\n", img->name, img->desc);
67 }
68 
70 {
71  if (!chan || !chan->tech)
72  return 0;
73  if (!chan->tech->send_image)
74  return 0;
75  return 1;
76 }
77 
78 static int file_exists(char *filename)
79 {
80  int res;
81  struct stat st;
82  res = stat(filename, &st);
83  if (!res)
84  return st.st_size;
85  return 0;
86 }
87 
88 static void make_filename(char *buf, int len, const char *filename, const char *preflang, char *ext)
89 {
90  if (filename[0] == '/') {
91  if (!ast_strlen_zero(preflang))
92  snprintf(buf, len, "%s-%s.%s", filename, preflang, ext);
93  else
94  snprintf(buf, len, "%s.%s", filename, ext);
95  } else {
96  if (!ast_strlen_zero(preflang))
97  snprintf(buf, len, "%s/%s/%s-%s.%s", ast_config_AST_DATA_DIR, "images", filename, preflang, ext);
98  else
99  snprintf(buf, len, "%s/%s/%s.%s", ast_config_AST_DATA_DIR, "images", filename, ext);
100  }
101 }
102 
103 struct ast_frame *ast_read_image(const char *filename, const char *preflang, int format)
104 {
105  struct ast_imager *i;
106  char buf[256];
107  char tmp[80];
108  char *e;
109  struct ast_imager *found = NULL;
110  int fd;
111  int len=0;
112  struct ast_frame *f = NULL;
113 
115  AST_RWLIST_TRAVERSE(&imagers, i, list) {
116  if (i->format & format) {
117  char *stringp=NULL;
118  ast_copy_string(tmp, i->exts, sizeof(tmp));
119  stringp = tmp;
120  e = strsep(&stringp, "|");
121  while (e) {
122  make_filename(buf, sizeof(buf), filename, preflang, e);
123  if ((len = file_exists(buf))) {
124  found = i;
125  break;
126  }
127  make_filename(buf, sizeof(buf), filename, NULL, e);
128  if ((len = file_exists(buf))) {
129  found = i;
130  break;
131  }
132  e = strsep(&stringp, "|");
133  }
134  }
135  if (found)
136  break;
137  }
138 
139  if (found) {
140  fd = open(buf, O_RDONLY);
141  if (fd > -1) {
142  if (!found->identify || found->identify(fd)) {
143  /* Reset file pointer */
144  lseek(fd, 0, SEEK_SET);
145  f = found->read_image(fd, len);
146  } else
147  ast_log(LOG_WARNING, "%s does not appear to be a %s file\n", buf, found->name);
148  close(fd);
149  } else
150  ast_log(LOG_WARNING, "Unable to open '%s': %s\n", buf, strerror(errno));
151  } else
152  ast_log(LOG_WARNING, "Image file '%s' not found\n", filename);
153 
155 
156  return f;
157 }
158 
159 int ast_send_image(struct ast_channel *chan, const char *filename)
160 {
161  struct ast_frame *f;
162  int res = -1;
163  if (chan->tech->send_image) {
164  f = ast_read_image(filename, chan->language, -1);
165  if (f) {
166  res = chan->tech->send_image(chan, f);
167  ast_frfree(f);
168  }
169  }
170  return res;
171 }
172 
173 static char *handle_core_show_image_formats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
174 {
175 #define FORMAT "%10s %10s %50s %10s\n"
176 #define FORMAT2 "%10s %10s %50s %10s\n"
177  struct ast_imager *i;
178  int count_fmt = 0;
179 
180  switch (cmd) {
181  case CLI_INIT:
182  e->command = "core show image formats";
183  e->usage =
184  "Usage: core show image formats\n"
185  " Displays currently registered image formats (if any).\n";
186  return NULL;
187  case CLI_GENERATE:
188  return NULL;
189  }
190  if (a->argc != 4)
191  return CLI_SHOWUSAGE;
192  ast_cli(a->fd, FORMAT, "Name", "Extensions", "Description", "Format");
193  ast_cli(a->fd, FORMAT, "----", "----------", "-----------", "------");
195  AST_RWLIST_TRAVERSE(&imagers, i, list) {
196  ast_cli(a->fd, FORMAT2, i->name, i->exts, i->desc, ast_getformatname(i->format));
197  count_fmt++;
198  }
200  ast_cli(a->fd, "\n%d image format%s registered.\n", count_fmt, count_fmt == 1 ? "" : "s");
201  return CLI_SUCCESS;
202 }
203 
204 static struct ast_cli_entry cli_image[] = {
205  AST_CLI_DEFINE(handle_core_show_image_formats, "Displays image formats")
206 };
207 
208 static void image_shutdown(void)
209 {
210  ast_cli_unregister_multiple(cli_image, ARRAY_LEN(cli_image));
211 }
212 
213 int ast_image_init(void)
214 {
215  ast_cli_register_multiple(cli_image, ARRAY_LEN(cli_image));
217  return 0;
218 }
structure associated with registering an image format
Definition: image.h:27
Main Channel structure associated with a channel.
Definition: channel.h:742
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
Asterisk locking-related definitions:
static void image_shutdown(void)
Definition: image.c:208
Asterisk main include file. File version handling, generic pbx functions.
static int file_exists(char *filename)
Definition: image.c:78
int(*const send_image)(struct ast_channel *chan, struct ast_frame *frame)
Display or send an image.
Definition: channel.h:560
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_cli_entry cli_image[]
Definition: image.c:204
char * strsep(char **str, const char *delims)
int ast_image_init(void)
Initialize image stuff Initializes all the various image stuff. Basically just registers the cli stuf...
Definition: image.c:213
#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:332
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
Support for translation of data formats. translate.c.
struct ast_frame * ast_read_image(const char *filename, const char *preflang, int format)
Make an image.
Definition: image.c:103
#define FORMAT2
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
int(* identify)(int fd)
Definition: image.h:33
descriptor for a cli entry.
Definition: cli.h:165
const int argc
Definition: cli.h:154
#define LOG_WARNING
Definition: logger.h:144
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:146
static char * handle_core_show_image_formats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: image.c:173
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static void make_filename(char *buf, int len, const char *filename, const char *preflang, char *ext)
Definition: image.c:88
const char * ext
Definition: http.c:112
int format
Definition: image.h:31
#define ast_verb(level,...)
Definition: logger.h:243
int ast_image_register(struct ast_imager *imgdrv)
Register image format.
Definition: image.c:50
int ast_send_image(struct ast_channel *chan, const char *filename)
Sends an image.
Definition: image.c:159
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:703
General Asterisk channel definitions for image handling.
General Asterisk PBX channel definitions.
Asterisk file paths, configured in asterisk.conf.
const int fd
Definition: cli.h:153
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define FORMAT
Scheduler Routines (derived from cheops)
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:998
const char * ast_config_AST_DATA_DIR
Definition: asterisk.c:262
int ast_supports_images(struct ast_channel *chan)
Check for image support on a channel.
Definition: image.c:69
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
#define CLI_SHOWUSAGE
Definition: cli.h:44
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_frame *(* read_image)(int fd, int len)
Definition: image.h:32
int errno
char * command
Definition: cli.h:180
static struct ast_format f[]
Definition: format_g726.c:181
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
Data structure associated with a single frame of data.
Definition: frame.h:142
char * desc
Definition: image.h:29
char * name
Definition: image.h:28
Definition: image.c:48
#define AST_RWLIST_REMOVE
Definition: linkedlists.h:870
void ast_image_unregister(struct ast_imager *imgdrv)
Unregister an image format.
Definition: image.c:59
#define ast_frfree(fr)
Definition: frame.h:583
static snd_pcm_format_t format
Definition: chan_alsa.c:93
struct ast_channel_tech * tech
Definition: channel.h:743
const ast_string_field language
Definition: channel.h:787
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180
char * exts
Definition: image.h:30