Wed Jan 8 2020 09:49:50

Asterisk developer's documentation


res_convert.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2005, 2006, Digium, Inc.
5  *
6  * redice li <redice_li@yahoo.com>
7  * Russell Bryant <russell@digium.com>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19 
20 /*! \file
21  *
22  * \brief file format conversion CLI command using Asterisk formats and translators
23  *
24  * \author redice li <redice_li@yahoo.com>
25  * \author Russell Bryant <russell@digium.com>
26  *
27  */
28 
29 /*** MODULEINFO
30  <support_level>core</support_level>
31  ***/
32 
33 #include "asterisk.h"
34 
35 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 328209 $")
36 
37 #include "asterisk/channel.h"
38 #include "asterisk/module.h"
39 #include "asterisk/cli.h"
40 #include "asterisk/file.h"
41 
42 /*! \brief Split the filename to basename and extension */
43 static int split_ext(char *filename, char **name, char **ext)
44 {
45  *name = *ext = filename;
46 
47  if ((*ext = strrchr(filename, '.'))) {
48  **ext = '\0';
49  (*ext)++;
50  }
51 
52  if (ast_strlen_zero(*name) || ast_strlen_zero(*ext))
53  return -1;
54 
55  return 0;
56 }
57 
58 /*!
59  * \brief Convert a file from one format to another
60  * \param e CLI entry
61  * \param cmd command number
62  * \param a list of cli arguments
63  * \retval CLI_SUCCESS on success.
64  * \retval CLI_SHOWUSAGE or CLI_FAILURE on failure.
65 */
66 static char *handle_cli_file_convert(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
67 {
68  char *ret = CLI_FAILURE;
69  struct ast_filestream *fs_in = NULL, *fs_out = NULL;
70  struct ast_frame *f;
71  struct timeval start;
72  int cost;
73  char *file_in = NULL, *file_out = NULL;
74  char *name_in, *ext_in, *name_out, *ext_out;
75 
76  switch (cmd) {
77  case CLI_INIT:
78  e->command = "file convert";
79  e->usage =
80  "Usage: file convert <file_in> <file_out>\n"
81  " Convert from file_in to file_out. If an absolute path\n"
82  " is not given, the default Asterisk sounds directory\n"
83  " will be used.\n\n"
84  " Example:\n"
85  " file convert tt-weasels.gsm tt-weasels.ulaw\n";
86  return NULL;
87  case CLI_GENERATE:
88  return NULL;
89  }
90 
91  /* ugly, can be removed when CLI entries have ast_module pointers */
93 
94  if (a->argc != 4 || ast_strlen_zero(a->argv[2]) || ast_strlen_zero(a->argv[3])) {
95  ret = CLI_SHOWUSAGE;
96  goto fail_out;
97  }
98 
99  file_in = ast_strdupa(a->argv[2]);
100  file_out = ast_strdupa(a->argv[3]);
101 
102  if (split_ext(file_in, &name_in, &ext_in)) {
103  ast_cli(a->fd, "'%s' is an invalid filename!\n", a->argv[2]);
104  goto fail_out;
105  }
106  if (!(fs_in = ast_readfile(name_in, ext_in, NULL, O_RDONLY, 0, 0))) {
107  ast_cli(a->fd, "Unable to open input file: %s\n", a->argv[2]);
108  goto fail_out;
109  }
110 
111  if (split_ext(file_out, &name_out, &ext_out)) {
112  ast_cli(a->fd, "'%s' is an invalid filename!\n", a->argv[3]);
113  goto fail_out;
114  }
115  if (!(fs_out = ast_writefile(name_out, ext_out, NULL, O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) {
116  ast_cli(a->fd, "Unable to open output file: %s\n", a->argv[3]);
117  goto fail_out;
118  }
119 
120  start = ast_tvnow();
121 
122  while ((f = ast_readframe(fs_in))) {
123  if (ast_writestream(fs_out, f)) {
124  ast_frfree(f);
125  ast_cli(a->fd, "Failed to convert %s.%s to %s.%s!\n", name_in, ext_in, name_out, ext_out);
126  goto fail_out;
127  }
128  ast_frfree(f);
129  }
130 
131  cost = ast_tvdiff_ms(ast_tvnow(), start);
132  ast_cli(a->fd, "Converted %s.%s to %s.%s in %dms\n", name_in, ext_in, name_out, ext_out, cost);
133  ret = CLI_SUCCESS;
134 
135 fail_out:
136  if (fs_out) {
137  ast_closestream(fs_out);
138  if (ret != CLI_SUCCESS)
139  ast_filedelete(name_out, ext_out);
140  }
141 
142  if (fs_in)
143  ast_closestream(fs_in);
144 
146 
147  return ret;
148 }
149 
150 static struct ast_cli_entry cli_convert[] = {
151  AST_CLI_DEFINE(handle_cli_file_convert, "Convert audio file")
152 };
153 
154 static int unload_module(void)
155 {
156  ast_cli_unregister_multiple(cli_convert, ARRAY_LEN(cli_convert));
157  return 0;
158 }
159 
160 static int load_module(void)
161 {
162  ast_cli_register_multiple(cli_convert, ARRAY_LEN(cli_convert));
164 }
165 
166 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "File format conversion CLI command");
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:396
Asterisk main include file. File version handling, generic pbx functions.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
void ast_module_unref(struct ast_module *)
Definition: loader.c:1312
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
descriptor for a cli entry.
Definition: cli.h:165
const int argc
Definition: cli.h:154
static char * handle_cli_file_convert(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Convert a file from one format to another.
Definition: res_convert.c:66
Definition: cli.h:146
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:931
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * ext
Definition: http.c:112
#define AST_FILE_MODE
Definition: asterisk.h:36
struct ast_module * self
Definition: module.h:227
const int fd
Definition: cli.h:153
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int unload_module(void)
Definition: res_convert.c:154
const char *const * argv
Definition: cli.h:155
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define CLI_SHOWUSAGE
Definition: cli.h:44
struct ast_frame * ast_readframe(struct ast_filestream *s)
Read a frame from a filestream.
Definition: file.c:737
static int load_module(void)
Definition: res_convert.c:160
struct ast_filestream * ast_writefile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
Starts writing a file.
Definition: file.c:1049
#define CLI_FAILURE
Definition: cli.h:45
static const char name[]
char * command
Definition: cli.h:180
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition: file.c:904
static struct ast_format f[]
Definition: format_g726.c:181
const char * usage
Definition: cli.h:171
static struct ast_cli_entry cli_convert[]
Definition: res_convert.c:150
#define CLI_SUCCESS
Definition: cli.h:43
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
Definition: mod_format.h:100
Standard Command Line Interface.
int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
Writes a frame to a stream.
Definition: file.c:150
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
struct ast_filestream * ast_readfile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
Starts reading from a file.
Definition: file.c:997
#define ast_frfree(fr)
Definition: frame.h:583
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
Asterisk module definitions.
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180
static int split_ext(char *filename, char **name, char **ext)
Split the filename to basename and extension.
Definition: res_convert.c:43
struct ast_module * ast_module_ref(struct ast_module *)
Definition: loader.c:1300