Asterisk - The Open Source Telephony Project  18.5.0
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 <[email protected]>
7  * Russell Bryant <[email protected]>
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 <[email protected]>
25  * \author Russell Bryant <[email protected]>
26  *
27  */
28 
29 /*** MODULEINFO
30  <support_level>core</support_level>
31  ***/
32 
33 #include "asterisk.h"
34 
35 #include "asterisk/channel.h"
36 #include "asterisk/module.h"
37 #include "asterisk/cli.h"
38 #include "asterisk/file.h"
39 
40 /*! \brief Split the filename to basename and extension */
41 static int split_ext(char *filename, char **name, char **ext)
42 {
43  *name = *ext = filename;
44 
45  if ((*ext = strrchr(filename, '.'))) {
46  **ext = '\0';
47  (*ext)++;
48  }
49 
50  if (ast_strlen_zero(*name) || ast_strlen_zero(*ext))
51  return -1;
52 
53  return 0;
54 }
55 
56 /*!
57  * \brief Convert a file from one format to another
58  * \param e CLI entry
59  * \param cmd command number
60  * \param a list of cli arguments
61  * \retval CLI_SUCCESS on success.
62  * \retval CLI_SHOWUSAGE or CLI_FAILURE on failure.
63 */
64 static char *handle_cli_file_convert(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
65 {
66  char *ret = CLI_FAILURE;
67  struct ast_filestream *fs_in = NULL, *fs_out = NULL;
68  struct ast_frame *f;
69  struct timeval start;
70  int cost;
71  char *file_in = NULL, *file_out = NULL;
72  char *name_in, *ext_in, *name_out, *ext_out;
73 
74  switch (cmd) {
75  case CLI_INIT:
76  e->command = "file convert";
77  e->usage =
78  "Usage: file convert <file_in> <file_out>\n"
79  " Convert from file_in to file_out. If an absolute path\n"
80  " is not given, the default Asterisk sounds directory\n"
81  " will be used.\n\n"
82  " Example:\n"
83  " file convert tt-weasels.gsm tt-weasels.ulaw\n";
84  return NULL;
85  case CLI_GENERATE:
86  return NULL;
87  }
88 
89  if (a->argc != 4 || ast_strlen_zero(a->argv[2]) || ast_strlen_zero(a->argv[3])) {
90  ret = CLI_SHOWUSAGE;
91  goto fail_out;
92  }
93 
94  file_in = ast_strdupa(a->argv[2]);
95  file_out = ast_strdupa(a->argv[3]);
96 
97  if (split_ext(file_in, &name_in, &ext_in)) {
98  ast_cli(a->fd, "'%s' is an invalid filename!\n", a->argv[2]);
99  goto fail_out;
100  }
101  if (!(fs_in = ast_readfile(name_in, ext_in, NULL, O_RDONLY, 0, 0))) {
102  ast_cli(a->fd, "Unable to open input file: %s\n", a->argv[2]);
103  goto fail_out;
104  }
105 
106  if (split_ext(file_out, &name_out, &ext_out)) {
107  ast_cli(a->fd, "'%s' is an invalid filename!\n", a->argv[3]);
108  goto fail_out;
109  }
110  if (!(fs_out = ast_writefile(name_out, ext_out, NULL, O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) {
111  ast_cli(a->fd, "Unable to open output file: %s\n", a->argv[3]);
112  goto fail_out;
113  }
114 
115  start = ast_tvnow();
116 
117  while ((f = ast_readframe(fs_in))) {
118  if (ast_writestream(fs_out, f)) {
119  ast_frfree(f);
120  ast_cli(a->fd, "Failed to convert %s.%s to %s.%s!\n", name_in, ext_in, name_out, ext_out);
121  goto fail_out;
122  }
123  ast_frfree(f);
124  }
125 
126  cost = ast_tvdiff_ms(ast_tvnow(), start);
127  ast_cli(a->fd, "Converted %s.%s to %s.%s in %dms\n", name_in, ext_in, name_out, ext_out, cost);
128  ret = CLI_SUCCESS;
129 
130 fail_out:
131  if (fs_out) {
132  ast_closestream(fs_out);
133  if (ret != CLI_SUCCESS)
134  ast_filedelete(name_out, ext_out);
135  }
136 
137  if (fs_in)
138  ast_closestream(fs_in);
139 
140  return ret;
141 }
142 
143 static struct ast_cli_entry cli_convert[] = {
144  AST_CLI_DEFINE(handle_cli_file_convert, "Convert audio file")
145 };
146 
147 static int unload_module(void)
148 {
149  ast_cli_unregister_multiple(cli_convert, ARRAY_LEN(cli_convert));
150  return 0;
151 }
152 
153 static int load_module(void)
154 {
155  ast_cli_register_multiple(cli_convert, ARRAY_LEN(cli_convert));
157 }
158 
159 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "File format conversion CLI command");
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:197
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
Asterisk main include file. File version handling, generic pbx functions.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
descriptor for a cli entry.
Definition: cli.h:171
const int argc
Definition: cli.h:160
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:64
Definition: cli.h:152
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
#define NULL
Definition: resample.c:96
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1098
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * ext
Definition: http.c:147
#define AST_FILE_MODE
Definition: asterisk.h:32
#define ast_strlen_zero(foo)
Definition: strings.h:52
General Asterisk PBX channel definitions.
const int fd
Definition: cli.h:159
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static int unload_module(void)
Definition: res_convert.c:147
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
struct ast_frame * ast_readframe(struct ast_filestream *s)
Read a frame from a filestream.
Definition: file.c:899
static int load_module(void)
Definition: res_convert.c:153
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:1361
#define CLI_FAILURE
Definition: cli.h:46
static const char name[]
Definition: cdr_mysql.c:74
char * command
Definition: cli.h:186
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition: file.c:1068
const char * usage
Definition: cli.h:177
static struct ast_cli_entry cli_convert[]
Definition: res_convert.c:143
#define CLI_SUCCESS
Definition: cli.h:44
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
Definition: mod_format.h:101
Standard Command Line Interface.
int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
Writes a frame to a stream.
Definition: file.c:209
#define ast_frfree(fr)
Data structure associated with a single frame of data.
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:1309
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
const ast_string_field filename
static int split_ext(char *filename, char **name, char **ext)
Split the filename to basename and extension.
Definition: res_convert.c:41
static struct test_val a