Allow Asterisk to compile under GCC 4.10
[asterisk/asterisk.git] / main / file.c
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 Generic File Format Support.
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$")
33
34 #include <dirent.h>
35 #include <sys/stat.h>
36 #include <sys/wait.h>
37 #include <math.h>
38
39 #include "asterisk/_private.h"  /* declare ast_file_init() */
40 #include "asterisk/paths.h"     /* use ast_config_AST_DATA_DIR */
41 #include "asterisk/mod_format.h"
42 #include "asterisk/cli.h"
43 #include "asterisk/channel.h"
44 #include "asterisk/sched.h"
45 #include "asterisk/translate.h"
46 #include "asterisk/utils.h"
47 #include "asterisk/lock.h"
48 #include "asterisk/app.h"
49 #include "asterisk/pbx.h"
50 #include "asterisk/linkedlists.h"
51 #include "asterisk/module.h"
52 #include "asterisk/astobj2.h"
53 #include "asterisk/test.h"
54 #include "asterisk/stasis.h"
55 #include "asterisk/json.h"
56 #include "asterisk/stasis_system.h"
57
58 /*! \brief
59  * The following variable controls the layout of localized sound files.
60  * If 0, use the historical layout with prefix just before the filename
61  * (i.e. digits/en/1.gsm , digits/it/1.gsm or default to digits/1.gsm),
62  * if 1 put the prefix at the beginning of the filename
63  * (i.e. en/digits/1.gsm, it/digits/1.gsm or default to digits/1.gsm).
64  * The latter permits a language to be entirely in one directory.
65  *
66  * This is settable in asterisk.conf.
67  */
68 int ast_language_is_prefix = 1;
69
70 static AST_RWLIST_HEAD_STATIC(formats, ast_format_def);
71
72 STASIS_MESSAGE_TYPE_DEFN(ast_format_register_type);
73 STASIS_MESSAGE_TYPE_DEFN(ast_format_unregister_type);
74
75 static struct ast_json *json_array_from_list(const char *list, const char *sep)
76 {
77         RAII_VAR(struct ast_json *, array, ast_json_array_create(), ast_json_unref);
78         char *stringp, *ext;
79
80         stringp = ast_strdupa(list);    /* this is in the stack so does not need to be freed */
81         if (!array || !stringp) {
82                 return NULL;
83         }
84
85         while ((ext = strsep(&stringp, sep))) {
86                 if (ast_json_array_append(array, ast_json_string_create(ext))) {
87                         return NULL;
88                 }
89         }
90
91         return ast_json_ref(array);
92 }
93
94 static int publish_format_update(const struct ast_format_def *f, struct stasis_message_type *type)
95 {
96         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
97         RAII_VAR(struct ast_json_payload *, json_payload, NULL, ao2_cleanup);
98         RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
99
100         json_object = ast_json_pack("{s: s, s: o}",
101                 "format", f->name,
102                 "extensions", json_array_from_list(f->exts, "|"));
103         if (!json_object) {
104                 return -1;
105         }
106
107         json_payload = ast_json_payload_create(json_object);
108         if (!json_payload) {
109                 return -1;
110         }
111
112         msg = stasis_message_create(type, json_payload);
113         if (!msg) {
114                 return -1;
115         }
116
117         stasis_publish(ast_system_topic(), msg);
118         return 0;
119 }
120
121 int __ast_format_def_register(const struct ast_format_def *f, struct ast_module *mod)
122 {
123         struct ast_format_def *tmp;
124
125         AST_RWLIST_WRLOCK(&formats);
126         AST_RWLIST_TRAVERSE(&formats, tmp, list) {
127                 if (!strcasecmp(f->name, tmp->name)) {
128                         AST_RWLIST_UNLOCK(&formats);
129                         ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name);
130                         return -1;
131                 }
132         }
133         if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
134                 AST_RWLIST_UNLOCK(&formats);
135                 return -1;
136         }
137         *tmp = *f;
138         tmp->module = mod;
139         if (tmp->buf_size) {
140                 /*
141                  * Align buf_size properly, rounding up to the machine-specific
142                  * alignment for pointers.
143                  */
144                 struct _test_align { void *a, *b; } p;
145                 int align = (char *)&p.b - (char *)&p.a;
146                 tmp->buf_size = ((f->buf_size + align - 1) / align) * align;
147         }
148
149         memset(&tmp->list, 0, sizeof(tmp->list));
150
151         AST_RWLIST_INSERT_HEAD(&formats, tmp, list);
152         AST_RWLIST_UNLOCK(&formats);
153         ast_verb(2, "Registered file format %s, extension(s) %s\n", f->name, f->exts);
154         publish_format_update(f, ast_format_register_type());
155
156         return 0;
157 }
158
159 int ast_format_def_unregister(const char *name)
160 {
161         struct ast_format_def *tmp;
162         int res = -1;
163
164         AST_RWLIST_WRLOCK(&formats);
165         AST_RWLIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) {
166                 if (!strcasecmp(name, tmp->name)) {
167                         AST_RWLIST_REMOVE_CURRENT(list);
168                         publish_format_update(tmp, ast_format_unregister_type());
169                         ast_free(tmp);
170                         res = 0;
171                 }
172         }
173         AST_RWLIST_TRAVERSE_SAFE_END;
174         AST_RWLIST_UNLOCK(&formats);
175
176         if (!res)
177                 ast_verb(2, "Unregistered format %s\n", name);
178         else
179                 ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name);
180
181         return res;
182 }
183
184 int ast_stopstream(struct ast_channel *tmp)
185 {
186         ast_channel_lock(tmp);
187
188         /* Stop a running stream if there is one */
189         if (ast_channel_stream(tmp)) {
190                 ast_closestream(ast_channel_stream(tmp));
191                 ast_channel_stream_set(tmp, NULL);
192                 if (ast_channel_oldwriteformat(tmp)->id && ast_set_write_format(tmp, ast_channel_oldwriteformat(tmp)))
193                         ast_log(LOG_WARNING, "Unable to restore format back to %s\n", ast_getformatname(ast_channel_oldwriteformat(tmp)));
194         }
195         /* Stop the video stream too */
196         if (ast_channel_vstream(tmp) != NULL) {
197                 ast_closestream(ast_channel_vstream(tmp));
198                 ast_channel_vstream_set(tmp, NULL);
199         }
200
201         ast_channel_unlock(tmp);
202
203         return 0;
204 }
205
206 int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
207 {
208         int res = -1;
209         if (f->frametype == AST_FRAME_VIDEO) {
210                 if (AST_FORMAT_GET_TYPE(fs->fmt->format.id) == AST_FORMAT_TYPE_AUDIO) {
211                         /* This is the audio portion.  Call the video one... */
212                         if (!fs->vfs && fs->filename) {
213                                 const char *type = ast_getformatname(&f->subclass.format);
214                                 fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode);
215                                 ast_debug(1, "Opened video output file\n");
216                         }
217                         if (fs->vfs)
218                                 return ast_writestream(fs->vfs, f);
219                         /* else ignore */
220                         return 0;
221                 }
222         } else if (f->frametype != AST_FRAME_VOICE) {
223                 ast_log(LOG_WARNING, "Tried to write non-voice frame\n");
224                 return -1;
225         }
226         if (ast_format_cmp(&f->subclass.format, &fs->fmt->format) != AST_FORMAT_CMP_NOT_EQUAL) {
227                 res =  fs->fmt->write(fs, f);
228                 if (res < 0)
229                         ast_log(LOG_WARNING, "Natural write failed\n");
230                 else if (res > 0)
231                         ast_log(LOG_WARNING, "Huh??\n");
232         } else {
233                 /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't
234                        the one we've setup a translator for, we do the "wrong thing" XXX */
235                 if (fs->trans && (ast_format_cmp(&f->subclass.format, &fs->lastwriteformat) != AST_FORMAT_CMP_EQUAL)) {
236                         ast_translator_free_path(fs->trans);
237                         fs->trans = NULL;
238                 }
239                 if (!fs->trans)
240                         fs->trans = ast_translator_build_path(&fs->fmt->format, &f->subclass.format);
241                 if (!fs->trans)
242                         ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n",
243                                 fs->fmt->name, ast_getformatname(&f->subclass.format));
244                 else {
245                         struct ast_frame *trf;
246                         ast_format_copy(&fs->lastwriteformat, &f->subclass.format);
247                         /* Get the translated frame but don't consume the original in case they're using it on another stream */
248                         if ((trf = ast_translate(fs->trans, f, 0))) {
249                                 struct ast_frame *cur;
250
251                                 /* the translator may have returned multiple frames, so process them */
252                                 for (cur = trf; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
253                                         if ((res = fs->fmt->write(fs, trf))) {
254                                                 ast_log(LOG_WARNING, "Translated frame write failed\n");
255                                                 break;
256                                         }
257                                 }
258                                 ast_frfree(trf);
259                         } else {
260                                 res = 0;
261                         }
262                 }
263         }
264         return res;
265 }
266
267 static int copy(const char *infile, const char *outfile)
268 {
269         int ifd, ofd, len;
270         char buf[4096]; /* XXX make it lerger. */
271
272         if ((ifd = open(infile, O_RDONLY)) < 0) {
273                 ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
274                 return -1;
275         }
276         if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, AST_FILE_MODE)) < 0) {
277                 ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
278                 close(ifd);
279                 return -1;
280         }
281         while ( (len = read(ifd, buf, sizeof(buf)) ) ) {
282                 int res;
283                 if (len < 0) {
284                         ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
285                         break;
286                 }
287                 /* XXX handle partial writes */
288                 res = write(ofd, buf, len);
289                 if (res != len) {
290                         ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
291                         len = -1; /* error marker */
292                         break;
293                 }
294         }
295         close(ifd);
296         close(ofd);
297         if (len < 0) {
298                 unlink(outfile);
299                 return -1; /* error */
300         }
301         return 0;       /* success */
302 }
303
304 /*!
305  * \brief construct a filename. Absolute pathnames are preserved,
306  * relative names are prefixed by the sounds/ directory.
307  * The wav49 suffix is replaced by 'WAV'.
308  * Returns a malloc'ed string to be freed by the caller.
309  */
310 static char *build_filename(const char *filename, const char *ext)
311 {
312         char *fn = NULL;
313
314         if (!strcmp(ext, "wav49"))
315                 ext = "WAV";
316
317         if (filename[0] == '/') {
318                 if (ast_asprintf(&fn, "%s.%s", filename, ext) < 0) {
319                         fn = NULL;
320                 }
321         } else {
322                 if (ast_asprintf(&fn, "%s/sounds/%s.%s",
323                              ast_config_AST_DATA_DIR, filename, ext) < 0) {
324                         fn = NULL;
325                 }
326         }
327         return fn;
328 }
329
330 /* compare type against the list 'exts' */
331 /* XXX need a better algorithm */
332 static int exts_compare(const char *exts, const char *type)
333 {
334         char tmp[256];
335         char *stringp = tmp, *ext;
336
337         ast_copy_string(tmp, exts, sizeof(tmp));
338         while ((ext = strsep(&stringp, "|"))) {
339                 if (!strcmp(ext, type))
340                         return 1;
341         }
342
343         return 0;
344 }
345
346 /*!
347  * \internal
348  * \brief Close the file stream by canceling any pending read / write callbacks
349  */
350 static void filestream_close(struct ast_filestream *f)
351 {
352         enum ast_format_type format_type = AST_FORMAT_GET_TYPE(f->fmt->format.id);
353
354         if (!f->owner) {
355                 return;
356         }
357
358         /* Stop a running stream if there is one */
359         switch (format_type)
360         {
361         case AST_FORMAT_TYPE_AUDIO:
362                 ast_channel_stream_set(f->owner, NULL);
363                 AST_SCHED_DEL_ACCESSOR(ast_channel_sched(f->owner), f->owner, ast_channel_streamid, ast_channel_streamid_set);
364                 ast_settimeout(f->owner, 0, NULL, NULL);
365                 break;
366         case AST_FORMAT_TYPE_VIDEO:
367                 ast_channel_vstream_set(f->owner, NULL);
368                 AST_SCHED_DEL_ACCESSOR(ast_channel_sched(f->owner), f->owner, ast_channel_vstreamid, ast_channel_vstreamid_set);
369                 break;
370         default:
371                 ast_log(AST_LOG_WARNING, "Unable to schedule deletion of filestream with unsupported type %s\n", f->fmt->name);
372                 break;
373         }
374 }
375
376 static void filestream_destructor(void *arg)
377 {
378         struct ast_filestream *f = arg;
379         int status;
380         int pid = -1;
381
382         /* Stop a running stream if there is one */
383         filestream_close(f);
384
385         /* destroy the translator on exit */
386         if (f->trans)
387                 ast_translator_free_path(f->trans);
388
389         if (f->fmt->close) {
390                 void (*closefn)(struct ast_filestream *) = f->fmt->close;
391                 closefn(f);
392         }
393
394         if (f->f) {
395                 fclose(f->f);
396         }
397
398         if (f->realfilename && f->filename) {
399                 pid = ast_safe_fork(0);
400                 if (!pid) {
401                         execl("/bin/mv", "mv", "-f", f->filename, f->realfilename, SENTINEL);
402                         _exit(1);
403                 }
404                 else if (pid > 0) {
405                         /* Block the parent until the move is complete.*/
406                         waitpid(pid, &status, 0);
407                 }
408         }
409
410         if (f->filename)
411                 free(f->filename);
412         if (f->realfilename)
413                 free(f->realfilename);
414         if (f->vfs)
415                 ast_closestream(f->vfs);
416         if (f->write_buffer) {
417                 ast_free(f->write_buffer);
418         }
419         if (f->orig_chan_name)
420                 free((void *) f->orig_chan_name);
421         ast_module_unref(f->fmt->module);
422 }
423
424 static struct ast_filestream *get_filestream(struct ast_format_def *fmt, FILE *bfile)
425 {
426         struct ast_filestream *s;
427
428         int l = sizeof(*s) + fmt->buf_size + fmt->desc_size;    /* total allocation size */
429         if ( (s = ao2_alloc(l, filestream_destructor)) == NULL)
430                 return NULL;
431         s->fmt = fmt;
432         s->f = bfile;
433
434         if (fmt->desc_size)
435                 s->_private = ((char *)(s + 1)) + fmt->buf_size;
436         if (fmt->buf_size)
437                 s->buf = (char *)(s + 1);
438         s->fr.src = fmt->name;
439         return s;
440 }
441
442 /*
443  * Default implementations of open and rewrite.
444  * Only use them if you don't have expensive stuff to do.
445  */
446 enum wrap_fn { WRAP_OPEN, WRAP_REWRITE };
447
448 static int fn_wrapper(struct ast_filestream *s, const char *comment, enum wrap_fn mode)
449 {
450         struct ast_format_def *f = s->fmt;
451         int ret = -1;
452         int (*openfn)(struct ast_filestream *s);
453
454         if (mode == WRAP_OPEN && (openfn = f->open) && openfn(s))
455                 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name);
456         else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment))
457                 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name);
458         else {
459                 /* preliminary checks succeed. update usecount */
460                 ast_module_ref(f->module);
461                 ret = 0;
462         }
463         return ret;
464 }
465
466 static int rewrite_wrapper(struct ast_filestream *s, const char *comment)
467 {
468         return fn_wrapper(s, comment, WRAP_REWRITE);
469 }
470
471 static int open_wrapper(struct ast_filestream *s)
472 {
473         return fn_wrapper(s, NULL, WRAP_OPEN);
474 }
475
476 enum file_action {
477         ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */
478         ACTION_DELETE,  /* delete file, return 0 on success, -1 on error */
479         ACTION_RENAME,  /* rename file. return 0 on success, -1 on error */
480         ACTION_OPEN,
481         ACTION_COPY     /* copy file. return 0 on success, -1 on error */
482 };
483
484 /*!
485  * \internal
486  * \brief perform various actions on a file. Second argument
487  * \note arg2 depends on the command:
488  *      unused for DELETE
489  *  optional ast_format_cap holding all the formats found for a file, for EXISTS.
490  *      destination file name (const char *) for COPY and RENAME
491  *      struct ast_channel * for OPEN
492  * if fmt is NULL, OPEN will return the first matching entry,
493  * whereas other functions will run on all matching entries.
494  */
495 static int filehelper(const char *filename, const void *arg2, const char *fmt, const enum file_action action)
496 {
497         struct ast_format_def *f;
498         int res = (action == ACTION_EXISTS) ? 0 : -1;
499
500         AST_RWLIST_RDLOCK(&formats);
501         /* Check for a specific format */
502         AST_RWLIST_TRAVERSE(&formats, f, list) {
503                 char *stringp, *ext = NULL;
504
505                 if (fmt && !exts_compare(f->exts, fmt))
506                         continue;
507
508                 /* Look for a file matching the supported extensions.
509                  * The file must exist, and for OPEN, must match
510                  * one of the formats supported by the channel.
511                  */
512                 stringp = ast_strdupa(f->exts); /* this is in the stack so does not need to be freed */
513                 while ( (ext = strsep(&stringp, "|")) ) {
514                         struct stat st;
515                         char *fn = build_filename(filename, ext);
516
517                         if (fn == NULL)
518                                 continue;
519
520                         if ( stat(fn, &st) ) { /* file not existent */
521                                 ast_free(fn);
522                                 continue;
523                         }
524                         /* for 'OPEN' we need to be sure that the format matches
525                          * what the channel can process
526                          */
527                         if (action == ACTION_OPEN) {
528                                 struct ast_channel *chan = (struct ast_channel *)arg2;
529                                 FILE *bfile;
530                                 struct ast_filestream *s;
531
532                                 if ((ast_format_cmp(ast_channel_writeformat(chan), &f->format) == AST_FORMAT_CMP_NOT_EQUAL) &&
533                                      !(((AST_FORMAT_GET_TYPE(f->format.id) == AST_FORMAT_TYPE_AUDIO) && fmt) ||
534                                           ((AST_FORMAT_GET_TYPE(f->format.id) == AST_FORMAT_TYPE_VIDEO) && fmt))) {
535                                         ast_free(fn);
536                                         continue;       /* not a supported format */
537                                 }
538                                 if ( (bfile = fopen(fn, "r")) == NULL) {
539                                         ast_free(fn);
540                                         continue;       /* cannot open file */
541                                 }
542                                 s = get_filestream(f, bfile);
543                                 if (!s) {
544                                         fclose(bfile);
545                                         ast_free(fn);   /* cannot allocate descriptor */
546                                         continue;
547                                 }
548                                 if (open_wrapper(s)) {
549                                         ast_free(fn);
550                                         ast_closestream(s);
551                                         continue;       /* cannot run open on file */
552                                 }
553                                 if (st.st_size == 0) {
554                                         ast_log(LOG_WARNING, "File %s detected to have zero size.\n", fn);
555                                 }
556                                 /* ok this is good for OPEN */
557                                 res = 1;        /* found */
558                                 s->lasttimeout = -1;
559                                 s->fmt = f;
560                                 s->trans = NULL;
561                                 s->filename = NULL;
562                                 if (AST_FORMAT_GET_TYPE(s->fmt->format.id) == AST_FORMAT_TYPE_AUDIO) {
563                                         if (ast_channel_stream(chan))
564                                                 ast_closestream(ast_channel_stream(chan));
565                                         ast_channel_stream_set(chan, s);
566                                 } else {
567                                         if (ast_channel_vstream(chan))
568                                                 ast_closestream(ast_channel_vstream(chan));
569                                         ast_channel_vstream_set(chan, s);
570                                 }
571                                 ast_free(fn);
572                                 break;
573                         }
574                         switch (action) {
575                         case ACTION_OPEN:
576                                 break;  /* will never get here */
577
578                         case ACTION_EXISTS:     /* return the matching format */
579                                 /* if arg2 is present, it is a format capabilities structure.
580                                  * Add this format to the set of formats this file can be played in */
581                                 if (arg2) {
582                                         ast_format_cap_add((struct ast_format_cap *) arg2, &f->format);
583                                 }
584                                 res = 1; /* file does exist and format it exists in is returned in arg2 */
585                                 break;
586
587                         case ACTION_DELETE:
588                                 if ( (res = unlink(fn)) )
589                                         ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno));
590                                 break;
591
592                         case ACTION_RENAME:
593                         case ACTION_COPY: {
594                                 char *nfn = build_filename((const char *)arg2, ext);
595                                 if (!nfn)
596                                         ast_log(LOG_WARNING, "Out of memory\n");
597                                 else {
598                                         res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn);
599                                         if (res)
600                                                 ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n",
601                                                         action == ACTION_COPY ? "copy" : "rename",
602                                                          fn, nfn, strerror(errno));
603                                         ast_free(nfn);
604                                 }
605                             }
606                                 break;
607
608                         default:
609                                 ast_log(LOG_WARNING, "Unknown helper %u\n", action);
610                         }
611                         ast_free(fn);
612                 }
613         }
614         AST_RWLIST_UNLOCK(&formats);
615         return res;
616 }
617
618 static int is_absolute_path(const char *filename)
619 {
620         return filename[0] == '/';
621 }
622
623 /*!
624  * \brief test if a file exists for a given format.
625  * \note result_cap is OPTIONAL
626  * \retval 1, true and result_cap represents format capabilities file exists in.
627  * \retval 0, false
628  */
629 static int fileexists_test(const char *filename, const char *fmt, const char *lang,
630                            char *buf, int buflen, struct ast_format_cap *result_cap)
631 {
632         if (buf == NULL) {
633                 return 0;
634         }
635
636         if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */
637                 if (lang) {
638                         snprintf(buf, buflen, "%s/%s", lang, filename);
639                 } else {
640                         snprintf(buf, buflen, "%s", filename);
641                 }
642         } else { /* old layout */
643                 strcpy(buf, filename);  /* first copy the full string */
644                 if (lang) {
645                         /* insert the language and suffix if needed */
646                         const char *c = strrchr(filename, '/');
647                         int offset = c ? c - filename + 1 : 0;  /* points right after the last '/' */
648                         snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset);
649                 }
650         }
651
652         return filehelper(buf, result_cap, fmt, ACTION_EXISTS);
653 }
654
655 /*!
656  * \brief helper routine to locate a file with a given format
657  * and language preference.
658  *
659  * \note Try preflang, preflang with stripped '_' suffices, or NULL.
660  *
661  * \note The last parameter(s) point to a buffer of sufficient size,
662  * which on success is filled with the matching filename.
663  *
664  * \param filename Name of the file.
665  * \param fmt Format to look for the file in. OPTIONAL
666  * \param preflang The perfered language
667  * \param buf Returns the matching filename
668  * \param buflen Size of the buf
669  * \param result_cap OPTIONAL format capabilities result structure
670  *        returns what formats the file was found in.
671  *
672  * \retval 1, true. file exists and result format is set
673  * \retval 0, false. file does not exist.
674  */
675 static int fileexists_core(const char *filename, const char *fmt, const char *preflang,
676                            char *buf, int buflen, struct ast_format_cap *result_cap)
677 {
678         char *lang;
679
680         if (buf == NULL) {
681                 return 0;
682         }
683
684         /* We try languages in the following order:
685          *    preflang (may include dialect and style codes)
686          *    lang (preflang without dialect - if any)
687          *    <none>
688          *    default (unless the same as preflang or lang without dialect)
689          */
690
691         lang = ast_strdupa(preflang);
692
693         /* Try preferred language, including removing any style or dialect codes */
694         while (!ast_strlen_zero(lang)) {
695                 char *end;
696
697                 if (fileexists_test(filename, fmt, lang, buf, buflen, result_cap)) {
698                         return 1;
699                 }
700
701                 if ((end = strrchr(lang, '_')) != NULL) {
702                         *end = '\0';
703                         continue;
704                 }
705
706                 break;
707         }
708
709         /* Try without any language */
710         if (fileexists_test(filename, fmt, NULL, buf, buflen, result_cap)) {
711                 return 1;
712         }
713
714         /* Finally try the default language unless it was already tried before */
715         if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) {
716                 if ((fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen, result_cap)) > 0) {
717                         return 1;
718                 }
719         }
720
721         return 0;
722 }
723
724 struct ast_filestream *ast_openstream(struct ast_channel *chan, const char *filename, const char *preflang)
725 {
726         return ast_openstream_full(chan, filename, preflang, 0);
727 }
728
729 struct ast_filestream *ast_openstream_full(struct ast_channel *chan, const char *filename, const char *preflang, int asis)
730 {
731         /*
732          * Use fileexists_core() to find a file in a compatible
733          * language and format, set up a suitable translator,
734          * and open the stream.
735          */
736         struct ast_format_cap *file_fmt_cap;
737         int res;
738         int buflen;
739         char *buf;
740
741         if (!asis) {
742                 /* do this first, otherwise we detect the wrong writeformat */
743                 ast_stopstream(chan);
744                 if (ast_channel_generator(chan))
745                         ast_deactivate_generator(chan);
746         }
747         if (preflang == NULL)
748                 preflang = "";
749         buflen = strlen(preflang) + strlen(filename) + 4;
750         buf = ast_alloca(buflen);
751
752         if (!(file_fmt_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK))) {
753                 return NULL;
754         }
755         if (!fileexists_core(filename, NULL, preflang, buf, buflen, file_fmt_cap) ||
756                 !ast_format_cap_has_type(file_fmt_cap, AST_FORMAT_TYPE_AUDIO)) {
757
758                 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
759                 file_fmt_cap = ast_format_cap_destroy(file_fmt_cap);
760                 return NULL;
761         }
762
763         /* Set the channel to a format we can work with and save off the previous format. */
764         ast_format_copy(ast_channel_oldwriteformat(chan), ast_channel_writeformat(chan));
765         /* Set the channel to the best format that exists for the file. */
766         res = ast_set_write_format_from_cap(chan, file_fmt_cap);
767         /* don't need this anymore now that the channel's write format is set. */
768         file_fmt_cap = ast_format_cap_destroy(file_fmt_cap);
769
770         if (res == -1) {        /* No format available that works with this channel */
771                 return NULL;
772         }
773         res = filehelper(buf, chan, NULL, ACTION_OPEN);
774         if (res >= 0)
775                 return ast_channel_stream(chan);
776         return NULL;
777 }
778
779 struct ast_filestream *ast_openvstream(struct ast_channel *chan, const char *filename, const char *preflang)
780 {
781         /* As above, but for video. But here we don't have translators
782          * so we must enforce a format.
783          */
784         struct ast_format tmp_fmt;
785         struct ast_format_cap *tmp_cap;
786         char *buf;
787         int buflen;
788         const char *fmt;
789         int fd;
790
791         if (preflang == NULL)
792                 preflang = "";
793         buflen = strlen(preflang) + strlen(filename) + 4;
794         buf = ast_alloca(buflen);
795
796         /* is the channel capable of video without translation ?*/
797         if (!ast_format_cap_has_type(ast_channel_nativeformats(chan), AST_FORMAT_TYPE_VIDEO)) {
798                 return NULL;
799         }
800         if (!(tmp_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK))) {
801                 return NULL;
802         }
803         /* Video is supported, so see what video formats exist for this file */
804         if (!fileexists_core(filename, NULL, preflang, buf, buflen, tmp_cap)) {
805                 tmp_cap = ast_format_cap_destroy(tmp_cap);
806                 return NULL;
807         }
808
809         /* iterate over file formats and pick the first one compatible with the channel's native formats */
810         ast_format_cap_iter_start(tmp_cap);
811         while (!ast_format_cap_iter_next(tmp_cap, &tmp_fmt)) {
812                 fmt = ast_getformatname(&tmp_fmt);
813                 if ((AST_FORMAT_GET_TYPE(tmp_fmt.id) != AST_FORMAT_TYPE_VIDEO) ||
814                         !ast_format_cap_iscompatible(ast_channel_nativeformats(chan), &tmp_fmt)) {
815                         continue;
816                 }
817
818                 fd = filehelper(buf, chan, fmt, ACTION_OPEN);
819                 if (fd >= 0) {
820                         ast_format_cap_iter_end(tmp_cap);
821                         tmp_cap = ast_format_cap_destroy(tmp_cap);
822                         return ast_channel_vstream(chan);
823                 }
824                 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
825         }
826         ast_format_cap_iter_end(tmp_cap);
827         tmp_cap = ast_format_cap_destroy(tmp_cap);
828
829         return NULL;
830 }
831
832 static struct ast_frame *read_frame(struct ast_filestream *s, int *whennext)
833 {
834         struct ast_frame *fr, *new_fr;
835
836         if (!s || !s->fmt) {
837                 return NULL;
838         }
839
840         if (!(fr = s->fmt->read(s, whennext))) {
841                 return NULL;
842         }
843
844         if (!(new_fr = ast_frisolate(fr))) {
845                 ast_frfree(fr);
846                 return NULL;
847         }
848
849         if (new_fr != fr) {
850                 ast_frfree(fr);
851                 fr = new_fr;
852         }
853
854         return fr;
855 }
856
857 struct ast_frame *ast_readframe(struct ast_filestream *s)
858 {
859         int whennext = 0;
860
861         return read_frame(s, &whennext);
862 }
863
864 enum fsread_res {
865         FSREAD_FAILURE,
866         FSREAD_SUCCESS_SCHED,
867         FSREAD_SUCCESS_NOSCHED,
868 };
869
870 static int ast_fsread_audio(const void *data);
871
872 static enum fsread_res ast_readaudio_callback(struct ast_filestream *s)
873 {
874         int whennext = 0;
875
876         while (!whennext) {
877                 struct ast_frame *fr;
878
879                 if (s->orig_chan_name && strcasecmp(ast_channel_name(s->owner), s->orig_chan_name)) {
880                         goto return_failure;
881                 }
882
883                 fr = read_frame(s, &whennext);
884
885                 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
886                         if (fr) {
887                                 ast_log(LOG_WARNING, "Failed to write frame\n");
888                                 ast_frfree(fr);
889                         }
890                         goto return_failure;
891                 }
892
893                 if (fr) {
894                         ast_frfree(fr);
895                 }
896         }
897
898         if (whennext != s->lasttimeout) {
899                 if (ast_channel_timingfd(s->owner) > -1) {
900                         float samp_rate = (float) ast_format_rate(&s->fmt->format);
901                         unsigned int rate;
902
903                         rate = (unsigned int) roundf(samp_rate / ((float) whennext));
904
905                         ast_settimeout_full(s->owner, rate, ast_fsread_audio, s, 1);
906                 } else {
907                         ast_channel_streamid_set(s->owner, ast_sched_add(ast_channel_sched(s->owner), whennext / (ast_format_rate(&s->fmt->format) / 1000), ast_fsread_audio, s));
908                 }
909                 s->lasttimeout = whennext;
910                 return FSREAD_SUCCESS_NOSCHED;
911         }
912         return FSREAD_SUCCESS_SCHED;
913
914 return_failure:
915         ast_channel_streamid_set(s->owner, -1);
916         ast_settimeout(s->owner, 0, NULL, NULL);
917         return FSREAD_FAILURE;
918 }
919
920 static int ast_fsread_audio(const void *data)
921 {
922         struct ast_filestream *fs = (struct ast_filestream *)data;
923         enum fsread_res res;
924
925         res = ast_readaudio_callback(fs);
926
927         if (res == FSREAD_SUCCESS_SCHED)
928                 return 1;
929
930         return 0;
931 }
932
933 static int ast_fsread_video(const void *data);
934
935 static enum fsread_res ast_readvideo_callback(struct ast_filestream *s)
936 {
937         int whennext = 0;
938
939         while (!whennext) {
940                 struct ast_frame *fr = read_frame(s, &whennext);
941
942                 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
943                         if (fr) {
944                                 ast_log(LOG_WARNING, "Failed to write frame\n");
945                                 ast_frfree(fr);
946                         }
947                         ast_channel_vstreamid_set(s->owner, -1);
948                         return FSREAD_FAILURE;
949                 }
950
951                 if (fr) {
952                         ast_frfree(fr);
953                 }
954         }
955
956         if (whennext != s->lasttimeout) {
957                 ast_channel_vstreamid_set(s->owner, ast_sched_add(ast_channel_sched(s->owner), whennext / (ast_format_rate(&s->fmt->format) / 1000), ast_fsread_video, s));
958                 s->lasttimeout = whennext;
959                 return FSREAD_SUCCESS_NOSCHED;
960         }
961
962         return FSREAD_SUCCESS_SCHED;
963 }
964
965 static int ast_fsread_video(const void *data)
966 {
967         struct ast_filestream *fs = (struct ast_filestream *)data;
968         enum fsread_res res;
969
970         res = ast_readvideo_callback(fs);
971
972         if (res == FSREAD_SUCCESS_SCHED)
973                 return 1;
974
975         return 0;
976 }
977
978 int ast_applystream(struct ast_channel *chan, struct ast_filestream *s)
979 {
980         s->owner = chan;
981         return 0;
982 }
983
984 int ast_playstream(struct ast_filestream *s)
985 {
986         enum fsread_res res;
987
988         if (AST_FORMAT_GET_TYPE(s->fmt->format.id) == AST_FORMAT_TYPE_AUDIO)
989                 res = ast_readaudio_callback(s);
990         else
991                 res = ast_readvideo_callback(s);
992
993         return (res == FSREAD_FAILURE) ? -1 : 0;
994 }
995
996 int ast_seekstream(struct ast_filestream *fs, off_t sample_offset, int whence)
997 {
998         return fs->fmt->seek(fs, sample_offset, whence);
999 }
1000
1001 int ast_truncstream(struct ast_filestream *fs)
1002 {
1003         return fs->fmt->trunc(fs);
1004 }
1005
1006 off_t ast_tellstream(struct ast_filestream *fs)
1007 {
1008         return fs->fmt->tell(fs);
1009 }
1010
1011 int ast_stream_fastforward(struct ast_filestream *fs, off_t ms)
1012 {
1013         return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
1014 }
1015
1016 int ast_stream_rewind(struct ast_filestream *fs, off_t ms)
1017 {
1018         return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
1019 }
1020
1021 int ast_closestream(struct ast_filestream *f)
1022 {
1023         /* This used to destroy the filestream, but it now just decrements a refcount.
1024          * We close the stream in order to quit queuing frames now, because we might
1025          * change the writeformat, which could result in a subsequent write error, if
1026          * the format is different. */
1027         if (f == NULL) {
1028                 return 0;
1029         }
1030         filestream_close(f);
1031         ao2_ref(f, -1);
1032         return 0;
1033 }
1034
1035
1036 /*
1037  * Look the various language-specific places where a file could exist.
1038  */
1039 int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
1040 {
1041         char *buf;
1042         int buflen;
1043
1044         if (preflang == NULL)
1045                 preflang = "";
1046         buflen = strlen(preflang) + strlen(filename) + 4;       /* room for everything */
1047         buf = ast_alloca(buflen);
1048         return fileexists_core(filename, fmt, preflang, buf, buflen, NULL) ? 1 : 0;
1049 }
1050
1051 int ast_filedelete(const char *filename, const char *fmt)
1052 {
1053         return filehelper(filename, NULL, fmt, ACTION_DELETE);
1054 }
1055
1056 int ast_filerename(const char *filename, const char *filename2, const char *fmt)
1057 {
1058         return filehelper(filename, filename2, fmt, ACTION_RENAME);
1059 }
1060
1061 int ast_filecopy(const char *filename, const char *filename2, const char *fmt)
1062 {
1063         return filehelper(filename, filename2, fmt, ACTION_COPY);
1064 }
1065
1066 int ast_streamfile(struct ast_channel *chan, const char *filename, const char *preflang)
1067 {
1068         struct ast_filestream *fs;
1069         struct ast_filestream *vfs=NULL;
1070         char fmt[256];
1071         off_t pos;
1072         int seekattempt;
1073         int res;
1074
1075         fs = ast_openstream(chan, filename, preflang);
1076         if (!fs) {
1077                 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), ast_channel_nativeformats(chan)), strerror(errno));
1078                 return -1;
1079         }
1080
1081         /* check to see if there is any data present (not a zero length file),
1082          * done this way because there is no where for ast_openstream_full to
1083          * return the file had no data. */
1084         pos = ftello(fs->f);
1085         seekattempt = fseeko(fs->f, -1, SEEK_END);
1086         if (seekattempt) {
1087                 if (errno == EINVAL) {
1088                         /* Zero-length file, as opposed to a pipe */
1089                         return 0;
1090                 } else {
1091                         ast_seekstream(fs, 0, SEEK_SET);
1092                 }
1093         } else {
1094                 fseeko(fs->f, pos, SEEK_SET);
1095         }
1096
1097         vfs = ast_openvstream(chan, filename, preflang);
1098         if (vfs) {
1099                 ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_getformatname(&vfs->fmt->format));
1100         }
1101
1102         if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_MASQ_NOSTREAM))
1103                 fs->orig_chan_name = ast_strdup(ast_channel_name(chan));
1104         if (ast_applystream(chan, fs))
1105                 return -1;
1106         if (vfs && ast_applystream(chan, vfs))
1107                 return -1;
1108         res = ast_playstream(fs);
1109         if (!res && vfs)
1110                 res = ast_playstream(vfs);
1111         ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", ast_channel_name(chan), filename, ast_getformatname(ast_channel_writeformat(chan)), preflang ? preflang : "default");
1112
1113         return res;
1114 }
1115
1116 struct ast_filestream *ast_readfile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
1117 {
1118         FILE *bfile;
1119         struct ast_format_def *f;
1120         struct ast_filestream *fs = NULL;
1121         char *fn;
1122         int format_found = 0;
1123
1124         AST_RWLIST_RDLOCK(&formats);
1125
1126         AST_RWLIST_TRAVERSE(&formats, f, list) {
1127                 fs = NULL;
1128                 if (!exts_compare(f->exts, type))
1129                         continue;
1130                 else
1131                         format_found = 1;
1132
1133                 fn = build_filename(filename, type);
1134                 if (!fn) {
1135                         continue;
1136                 }
1137                 errno = 0;
1138                 bfile = fopen(fn, "r");
1139
1140                 if (!bfile || (fs = get_filestream(f, bfile)) == NULL || open_wrapper(fs) ) {
1141                         ast_log(LOG_WARNING, "Unable to open %s\n", fn);
1142                         if (fs) {
1143                                 ast_closestream(fs);
1144                         }
1145                         fs = NULL;
1146                         bfile = NULL;
1147                         ast_free(fn);
1148                         break;
1149                 }
1150                 /* found it */
1151                 fs->trans = NULL;
1152                 fs->fmt = f;
1153                 fs->flags = flags;
1154                 fs->mode = mode;
1155                 fs->filename = ast_strdup(filename);
1156                 fs->vfs = NULL;
1157                 ast_free(fn);
1158                 break;
1159         }
1160
1161         AST_RWLIST_UNLOCK(&formats);
1162         if (!format_found)
1163                 ast_log(LOG_WARNING, "No such format '%s'\n", type);
1164
1165         return fs;
1166 }
1167
1168 struct ast_filestream *ast_writefile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
1169 {
1170         int fd, myflags = 0;
1171         /* compiler claims this variable can be used before initialization... */
1172         FILE *bfile = NULL;
1173         struct ast_format_def *f;
1174         struct ast_filestream *fs = NULL;
1175         char *buf = NULL;
1176         size_t size = 0;
1177         int format_found = 0;
1178
1179         AST_RWLIST_RDLOCK(&formats);
1180
1181         /* set the O_TRUNC flag if and only if there is no O_APPEND specified */
1182         /* We really can't use O_APPEND as it will break WAV header updates */
1183         if (flags & O_APPEND) {
1184                 flags &= ~O_APPEND;
1185         } else {
1186                 myflags = O_TRUNC;
1187         }
1188
1189         myflags |= O_WRONLY | O_CREAT;
1190
1191         /* XXX need to fix this - we should just do the fopen,
1192          * not open followed by fdopen()
1193          */
1194         AST_RWLIST_TRAVERSE(&formats, f, list) {
1195                 char *fn, *orig_fn = NULL;
1196                 if (fs)
1197                         break;
1198
1199                 if (!exts_compare(f->exts, type))
1200                         continue;
1201                 else
1202                         format_found = 1;
1203
1204                 fn = build_filename(filename, type);
1205                 if (!fn) {
1206                         continue;
1207                 }
1208                 fd = open(fn, flags | myflags, mode);
1209                 if (fd > -1) {
1210                         /* fdopen() the resulting file stream */
1211                         bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
1212                         if (!bfile) {
1213                                 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
1214                                 close(fd);
1215                                 fd = -1;
1216                         }
1217                 }
1218
1219                 if (ast_opt_cache_record_files && (fd > -1)) {
1220                         char *c;
1221
1222                         fclose(bfile);  /* this also closes fd */
1223                         /*
1224                           We touch orig_fn just as a place-holder so other things (like vmail) see the file is there.
1225                           What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place.
1226                         */
1227                         orig_fn = ast_strdupa(fn);
1228                         for (c = fn; *c; c++)
1229                                 if (*c == '/')
1230                                         *c = '_';
1231
1232                         size = strlen(fn) + strlen(record_cache_dir) + 2;
1233                         buf = ast_alloca(size);
1234                         strcpy(buf, record_cache_dir);
1235                         strcat(buf, "/");
1236                         strcat(buf, fn);
1237                         ast_free(fn);
1238                         fn = buf;
1239                         fd = open(fn, flags | myflags, mode);
1240                         if (fd > -1) {
1241                                 /* fdopen() the resulting file stream */
1242                                 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
1243                                 if (!bfile) {
1244                                         ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
1245                                         close(fd);
1246                                         fd = -1;
1247                                 }
1248                         }
1249                 }
1250                 if (fd > -1) {
1251                         errno = 0;
1252                         fs = get_filestream(f, bfile);
1253                         if (fs) {
1254                                 if ((fs->write_buffer = ast_malloc(32768))) {
1255                                         setvbuf(fs->f, fs->write_buffer, _IOFBF, 32768);
1256                                 }
1257                         }
1258                         if (!fs || rewrite_wrapper(fs, comment)) {
1259                                 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn);
1260                                 close(fd);
1261                                 if (orig_fn) {
1262                                         unlink(fn);
1263                                         unlink(orig_fn);
1264                                 }
1265                                 if (fs) {
1266                                         ast_closestream(fs);
1267                                         fs = NULL;
1268                                 }
1269                                 if (!buf) {
1270                                         ast_free(fn);
1271                                 }
1272                                 continue;
1273                         }
1274                         fs->trans = NULL;
1275                         fs->fmt = f;
1276                         fs->flags = flags;
1277                         fs->mode = mode;
1278                         if (orig_fn) {
1279                                 fs->realfilename = ast_strdup(orig_fn);
1280                                 fs->filename = ast_strdup(fn);
1281                         } else {
1282                                 fs->realfilename = NULL;
1283                                 fs->filename = ast_strdup(filename);
1284                         }
1285                         fs->vfs = NULL;
1286                         /* If truncated, we'll be at the beginning; if not truncated, then append */
1287                         f->seek(fs, 0, SEEK_END);
1288                 } else if (errno != EEXIST) {
1289                         ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
1290                         if (orig_fn)
1291                                 unlink(orig_fn);
1292                 }
1293                 /* if buf != NULL then fn is already free and pointing to it */
1294                 if (!buf)
1295                         ast_free(fn);
1296         }
1297
1298         AST_RWLIST_UNLOCK(&formats);
1299
1300         if (!format_found)
1301                 ast_log(LOG_WARNING, "No such format '%s'\n", type);
1302
1303         return fs;
1304 }
1305
1306 static void waitstream_control(struct ast_channel *c,
1307                 enum ast_waitstream_fr_cb_values type,
1308                 ast_waitstream_fr_cb cb,
1309                 int skip_ms)
1310 {
1311         switch (type)
1312         {
1313         case AST_WAITSTREAM_CB_FASTFORWARD:
1314                 {
1315                         int eoftest;
1316                         ast_stream_fastforward(ast_channel_stream(c), skip_ms);
1317                         eoftest = fgetc(ast_channel_stream(c)->f);
1318                         if (feof(ast_channel_stream(c)->f)) {
1319                                 ast_stream_rewind(ast_channel_stream(c), skip_ms);
1320                         } else {
1321                                 ungetc(eoftest, ast_channel_stream(c)->f);
1322                         }
1323                 }
1324                 break;
1325         case AST_WAITSTREAM_CB_REWIND:
1326                 ast_stream_rewind(ast_channel_stream(c), skip_ms);
1327                 break;
1328         default:
1329                 break;
1330         }
1331
1332         if (cb) {
1333                 long ms_len = ast_tellstream(ast_channel_stream(c)) / (ast_format_rate(&ast_channel_stream(c)->fmt->format) / 1000);
1334                 cb(c, ms_len, type);
1335         }
1336
1337         ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1338                 "Control: %s\r\n"
1339                 "SkipMs: %d\r\n",
1340                 ast_channel_name(c),
1341                 (type == AST_WAITSTREAM_CB_FASTFORWARD) ? "FastForward" : "Rewind",
1342                 skip_ms);
1343 }
1344
1345 /*!
1346  * \brief the core of all waitstream() functions
1347  */
1348 static int waitstream_core(struct ast_channel *c,
1349         const char *breakon,
1350         const char *forward,
1351         const char *reverse,
1352         int skip_ms,
1353         int audiofd,
1354         int cmdfd,
1355         const char *context,
1356         ast_waitstream_fr_cb cb)
1357 {
1358         const char *orig_chan_name = NULL;
1359
1360         int err = 0;
1361
1362         if (!breakon)
1363                 breakon = "";
1364         if (!forward)
1365                 forward = "";
1366         if (!reverse)
1367                 reverse = "";
1368
1369         /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
1370         ast_set_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
1371
1372         if (ast_test_flag(ast_channel_flags(c), AST_FLAG_MASQ_NOSTREAM))
1373                 orig_chan_name = ast_strdupa(ast_channel_name(c));
1374
1375         if (ast_channel_stream(c) && cb) {
1376                 long ms_len = ast_tellstream(ast_channel_stream(c)) / (ast_format_rate(&ast_channel_stream(c)->fmt->format) / 1000);
1377                 cb(c, ms_len, AST_WAITSTREAM_CB_START);
1378         }
1379
1380         while (ast_channel_stream(c)) {
1381                 int res;
1382                 int ms;
1383
1384                 if (orig_chan_name && strcasecmp(orig_chan_name, ast_channel_name(c))) {
1385                         ast_stopstream(c);
1386                         err = 1;
1387                         break;
1388                 }
1389
1390                 ms = ast_sched_wait(ast_channel_sched(c));
1391
1392                 if (ms < 0 && !ast_channel_timingfunc(c)) {
1393                         ast_stopstream(c);
1394                         break;
1395                 }
1396                 if (ms < 0)
1397                         ms = 1000;
1398                 if (cmdfd < 0) {
1399                         res = ast_waitfor(c, ms);
1400                         if (res < 0) {
1401                                 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
1402                                 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
1403                                 return res;
1404                         }
1405                 } else {
1406                         int outfd;
1407                         struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
1408                         if (!rchan && (outfd < 0) && (ms)) {
1409                                 /* Continue */
1410                                 if (errno == EINTR)
1411                                         continue;
1412                                 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
1413                                 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
1414                                 return -1;
1415                         } else if (outfd > -1) { /* this requires cmdfd set */
1416                                 /* The FD we were watching has something waiting */
1417                                 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
1418                                 return 1;
1419                         }
1420                         /* if rchan is set, it is 'c' */
1421                         res = rchan ? 1 : 0; /* map into 'res' values */
1422                 }
1423                 if (res > 0) {
1424                         struct ast_frame *fr = ast_read(c);
1425                         if (!fr) {
1426                                 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
1427                                 return -1;
1428                         }
1429                         switch (fr->frametype) {
1430                         case AST_FRAME_DTMF_END:
1431                                 if (context) {
1432                                         const char exten[2] = { fr->subclass.integer, '\0' };
1433                                         if (ast_exists_extension(c, context, exten, 1,
1434                                                 S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
1435                                                 res = fr->subclass.integer;
1436                                                 ast_frfree(fr);
1437                                                 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
1438                                                 return res;
1439                                         }
1440                                 } else {
1441                                         res = fr->subclass.integer;
1442                                         if (strchr(forward, res)) {
1443                                                 waitstream_control(c, AST_WAITSTREAM_CB_FASTFORWARD, cb, skip_ms);
1444                                         } else if (strchr(reverse, res)) {
1445                                                 waitstream_control(c, AST_WAITSTREAM_CB_REWIND, cb, skip_ms);
1446                                         } else if (strchr(breakon, res)) {
1447                                                 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1448                                                         "Control: %s\r\n",
1449                                                         ast_channel_name(c),
1450                                                         "Break");
1451
1452                                                 ast_frfree(fr);
1453                                                 ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
1454                                                 return res;
1455                                         }
1456                                 }
1457                                 break;
1458                         case AST_FRAME_CONTROL:
1459                                 switch (fr->subclass.integer) {
1460                                 case AST_CONTROL_STREAM_STOP:
1461                                 case AST_CONTROL_STREAM_SUSPEND:
1462                                 case AST_CONTROL_STREAM_RESTART:
1463                                         /* Fall-through and break out */
1464                                         ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1465                                                 "Control: %s\r\n",
1466                                                 ast_channel_name(c),
1467                                                 "Break");
1468                                         res = fr->subclass.integer;
1469                                         ast_frfree(fr);
1470                                         ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
1471                                         return res;
1472                                 case AST_CONTROL_STREAM_REVERSE:
1473                                         if (!skip_ms) {
1474                                                 skip_ms = 3000;
1475                                         }
1476                                         waitstream_control(c, AST_WAITSTREAM_CB_REWIND, cb, skip_ms);
1477                                         break;
1478                                 case AST_CONTROL_STREAM_FORWARD:
1479                                         if (!skip_ms) {
1480                                                 skip_ms = 3000;
1481                                         }
1482                                         waitstream_control(c, AST_WAITSTREAM_CB_FASTFORWARD, cb, skip_ms);
1483                                         break;
1484                                 case AST_CONTROL_HANGUP:
1485                                 case AST_CONTROL_BUSY:
1486                                 case AST_CONTROL_CONGESTION:
1487                                         ast_frfree(fr);
1488                                         ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
1489                                         return -1;
1490                                 case AST_CONTROL_RINGING:
1491                                 case AST_CONTROL_ANSWER:
1492                                 case AST_CONTROL_VIDUPDATE:
1493                                 case AST_CONTROL_SRCUPDATE:
1494                                 case AST_CONTROL_SRCCHANGE:
1495                                 case AST_CONTROL_HOLD:
1496                                 case AST_CONTROL_UNHOLD:
1497                                 case AST_CONTROL_CONNECTED_LINE:
1498                                 case AST_CONTROL_REDIRECTING:
1499                                 case AST_CONTROL_AOC:
1500                                 case AST_CONTROL_UPDATE_RTP_PEER:
1501                                 case AST_CONTROL_PVT_CAUSE_CODE:
1502                                 case -1:
1503                                         /* Unimportant */
1504                                         break;
1505                                 default:
1506                                         ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass.integer);
1507                                 }
1508                                 break;
1509                         case AST_FRAME_VOICE:
1510                                 /* Write audio if appropriate */
1511                                 if (audiofd > -1) {
1512                                         if (write(audiofd, fr->data.ptr, fr->datalen) < 0) {
1513                                                 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
1514                                         }
1515                                 }
1516                         default:
1517                                 /* Ignore all others */
1518                                 break;
1519                         }
1520                         ast_frfree(fr);
1521                 }
1522                 ast_sched_runq(ast_channel_sched(c));
1523         }
1524
1525         ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
1526
1527         return (err || ast_channel_softhangup_internal_flag(c)) ? -1 : 0;
1528 }
1529
1530 int ast_waitstream_fr_w_cb(struct ast_channel *c,
1531         const char *breakon,
1532         const char *forward,
1533         const char *reverse,
1534         int ms,
1535         ast_waitstream_fr_cb cb)
1536 {
1537         return waitstream_core(c, breakon, forward, reverse, ms,
1538                 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */, cb);
1539 }
1540
1541 int ast_waitstream_fr(struct ast_channel *c, const char *breakon, const char *forward, const char *reverse, int ms)
1542 {
1543         return waitstream_core(c, breakon, forward, reverse, ms,
1544                 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */, NULL /* no callback */);
1545 }
1546
1547 /*! \internal
1548  * \brief Clean up the return value of a waitstream call
1549  *
1550  * It's possible for a control frame to come in from an external source and break the
1551  * playback. From a consumer of most ast_waitstream_* function callers, this should
1552  * appear like normal playback termination, i.e., return 0 and not the value of the
1553  * control frame.
1554  */
1555 static int sanitize_waitstream_return(int return_value)
1556 {
1557         switch (return_value) {
1558         case AST_CONTROL_STREAM_STOP:
1559         case AST_CONTROL_STREAM_SUSPEND:
1560         case AST_CONTROL_STREAM_RESTART:
1561                 /* Fall through and set return_value to 0 */
1562                 return_value = 0;
1563                 break;
1564         default:
1565                 /* Do nothing */
1566                 break;
1567         }
1568
1569         return return_value;
1570 }
1571
1572 int ast_waitstream(struct ast_channel *c, const char *breakon)
1573 {
1574         int res;
1575
1576         res = waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL, NULL /* no callback */);
1577
1578         return sanitize_waitstream_return(res);
1579 }
1580
1581 int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int cmdfd)
1582 {
1583         int res;
1584
1585         res = waitstream_core(c, breakon, NULL, NULL, 0,
1586                 audiofd, cmdfd, NULL /* no context */, NULL /* no callback */);
1587
1588         return sanitize_waitstream_return(res);
1589 }
1590
1591 int ast_waitstream_exten(struct ast_channel *c, const char *context)
1592 {
1593         int res;
1594
1595         /* Waitstream, with return in the case of a valid 1 digit extension */
1596         /* in the current or specified context being pressed */
1597         if (!context)
1598                 context = ast_channel_context(c);
1599         res = waitstream_core(c, NULL, NULL, NULL, 0,
1600                 -1, -1, context, NULL /* no callback */);
1601
1602         return sanitize_waitstream_return(res);
1603 }
1604
1605 /*
1606  * if the file name is non-empty, try to play it.
1607  * Return 0 if success, -1 if error, digit if interrupted by a digit.
1608  * If digits == "" then we can simply check for non-zero.
1609  */
1610 int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
1611 {
1612         int res = 0;
1613         if (!ast_strlen_zero(file)) {
1614                 ast_test_suite_event_notify("PLAYBACK", "Message: %s\r\nChannel: %s", file, ast_channel_name(chan));
1615                 res = ast_streamfile(chan, file, ast_channel_language(chan));
1616                 if (!res) {
1617                         res = ast_waitstream(chan, digits);
1618                 }
1619         }
1620         return res;
1621 }
1622
1623 char *ast_format_str_reduce(char *fmts)
1624 {
1625         struct ast_format_def *f;
1626         struct ast_format_def *fmts_ptr[AST_MAX_FORMATS];
1627         char *fmts_str[AST_MAX_FORMATS];
1628         char *stringp, *type;
1629         char *orig = fmts;
1630         int i, j, x, first, found = 0;
1631         int len = strlen(fmts) + 1;
1632         int res;
1633
1634         if (AST_RWLIST_RDLOCK(&formats)) {
1635                 ast_log(LOG_WARNING, "Unable to lock format list\n");
1636                 return NULL;
1637         }
1638
1639         stringp = ast_strdupa(fmts);
1640
1641         for (x = 0; (type = strsep(&stringp, "|")) && x < AST_MAX_FORMATS; x++) {
1642                 AST_RWLIST_TRAVERSE(&formats, f, list) {
1643                         if (exts_compare(f->exts, type)) {
1644                                 found = 1;
1645                                 break;
1646                         }
1647                 }
1648
1649                 fmts_str[x] = type;
1650                 if (found) {
1651                         fmts_ptr[x] = f;
1652                 } else {
1653                         fmts_ptr[x] = NULL;
1654                 }
1655         }
1656         AST_RWLIST_UNLOCK(&formats);
1657
1658         first = 1;
1659         for (i = 0; i < x; i++) {
1660                 /* ignore invalid entries */
1661                 if (!fmts_ptr[i]) {
1662                         ast_log(LOG_WARNING, "ignoring unknown format '%s'\n", fmts_str[i]);
1663                         continue;
1664                 }
1665
1666                 /* special handling for the first entry */
1667                 if (first) {
1668                         res = snprintf(fmts, len, "%s", fmts_str[i]);
1669                         fmts += res;
1670                         len -= res;
1671                         first = 0;
1672                         continue;
1673                 }
1674
1675                 found = 0;
1676                 for (j = 0; j < i; j++) {
1677                         /* this is a duplicate */
1678                         if (fmts_ptr[j] == fmts_ptr[i]) {
1679                                 found = 1;
1680                                 break;
1681                         }
1682                 }
1683
1684                 if (!found) {
1685                         res = snprintf(fmts, len, "|%s", fmts_str[i]);
1686                         fmts += res;
1687                         len -= res;
1688                 }
1689         }
1690
1691         if (first) {
1692                 ast_log(LOG_WARNING, "no known formats found in format list (%s)\n", orig);
1693                 return NULL;
1694         }
1695
1696         return orig;
1697 }
1698
1699 static char *handle_cli_core_show_file_formats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1700 {
1701 #define FORMAT "%-10s %-10s %-20s\n"
1702 #define FORMAT2 "%-10s %-10s %-20s\n"
1703         struct ast_format_def *f;
1704         int count_fmt = 0;
1705
1706         switch (cmd) {
1707         case CLI_INIT:
1708                 e->command = "core show file formats";
1709                 e->usage =
1710                         "Usage: core show file formats\n"
1711                         "       Displays currently registered file formats (if any).\n";
1712                 return NULL;
1713         case CLI_GENERATE:
1714                 return NULL;
1715         }
1716
1717         if (a->argc != 4)
1718                 return CLI_SHOWUSAGE;
1719
1720         ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions");
1721         ast_cli(a->fd, FORMAT, "------", "----", "----------");
1722
1723         AST_RWLIST_RDLOCK(&formats);
1724         AST_RWLIST_TRAVERSE(&formats, f, list) {
1725                 ast_cli(a->fd, FORMAT2, ast_getformatname(&f->format), f->name, f->exts);
1726                 count_fmt++;
1727         }
1728         AST_RWLIST_UNLOCK(&formats);
1729         ast_cli(a->fd, "%d file formats registered.\n", count_fmt);
1730         return CLI_SUCCESS;
1731 #undef FORMAT
1732 #undef FORMAT2
1733 }
1734
1735 const struct ast_format *ast_get_format_for_file_ext(const char *file_ext)
1736 {
1737         struct ast_format_def *f;
1738         SCOPED_RDLOCK(lock, &formats.lock);
1739         AST_RWLIST_TRAVERSE(&formats, f, list) {
1740                 if (exts_compare(f->exts, file_ext)) {
1741                         return &f->format;
1742                 }
1743         }
1744
1745         return NULL;
1746 }
1747
1748 static struct ast_cli_entry cli_file[] = {
1749         AST_CLI_DEFINE(handle_cli_core_show_file_formats, "Displays file formats")
1750 };
1751
1752 static void file_shutdown(void)
1753 {
1754         ast_cli_unregister_multiple(cli_file, ARRAY_LEN(cli_file));
1755         STASIS_MESSAGE_TYPE_CLEANUP(ast_format_register_type);
1756         STASIS_MESSAGE_TYPE_CLEANUP(ast_format_unregister_type);
1757 }
1758
1759 int ast_file_init(void)
1760 {
1761         STASIS_MESSAGE_TYPE_INIT(ast_format_register_type);
1762         STASIS_MESSAGE_TYPE_INIT(ast_format_unregister_type);
1763         ast_cli_register_multiple(cli_file, ARRAY_LEN(cli_file));
1764         ast_register_atexit(file_shutdown);
1765         return 0;
1766 }