formatting cleanup on the header,
[asterisk/asterisk.git] / apps / app_softhangup.c
index a011c32..7af8525 100644 (file)
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-
 #include "asterisk/file.h"
-#include "asterisk/logger.h"
 #include "asterisk/channel.h"
 #include "asterisk/pbx.h"
 #include "asterisk/module.h"
 #include "asterisk/lock.h"
+#include "asterisk/app.h"
 
 static char *synopsis = "Soft Hangup Application";
 
-static char *desc = "  SoftHangup(Technology/resource|options)\n"
+static char *desc = "  SoftHangup(Technology/resource[,options]):\n"
 "Hangs up the requested channel.  If there are no channels to hangup,\n"
 "the application will report it.\n"
-"- 'options' may contain the following letter:\n"
-"     'a' : hang up all channels on a specified device instead of a single resource\n";
+"  Options:\n"
+"     'a'  - hang up all channels on a specified device instead of a single resource\n";
 
 static char *app = "SoftHangup";
 
+enum {
+       OPTION_ALL = (1 << 0),
+};
+
+AST_APP_OPTIONS(app_opts,{
+       AST_APP_OPTION('a', OPTION_ALL),
+});
 
 static int softhangup_exec(struct ast_channel *chan, void *data)
 {
-       struct ast_module_user *u;
-       struct ast_channel *c=NULL;
-       char *options, *cut, *cdata, *match;
-       char name[AST_CHANNEL_NAME] = "";
-       int all = 0;
+       struct ast_channel *c = NULL;
+       char *cut, *opts[0];
+       char name[AST_CHANNEL_NAME] = "", *parse;
+       struct ast_flags flags;
+       int lenmatch;
+       AST_DECLARE_APP_ARGS(args,
+               AST_APP_ARG(channel);
+               AST_APP_ARG(options);
+       );
        
        if (ast_strlen_zero(data)) {
-                ast_log(LOG_WARNING, "SoftHangup requires an argument (Technology/resource)\n");
+               ast_log(LOG_WARNING, "SoftHangup requires an argument (Technology/resource)\n");
                return 0;
        }
-       
-       u = ast_module_user_add(chan);
-
-       cdata = ast_strdupa(data);
-       match = strsep(&cdata, "|");
-       options = strsep(&cdata, "|");
-       all = options && strchr(options,'a');
-       c = ast_channel_walk_locked(NULL);
-       while (c) {
+
+       parse = ast_strdupa(data);
+       AST_STANDARD_APP_ARGS(args, parse);
+
+       if (args.argc == 2)
+               ast_app_parse_options(app_opts, &flags, opts, args.options);
+       lenmatch = strlen(args.channel);
+
+       for (c = ast_walk_channel_by_name_prefix_locked(NULL, args.channel, lenmatch);
+                c;
+                c = ast_walk_channel_by_name_prefix_locked(c, args.channel, lenmatch)) {
                ast_copy_string(name, c->name, sizeof(name));
-               ast_mutex_unlock(&c->lock);
-               /* XXX watch out, i think it is wrong to access c-> after unlocking! */
-               if (all) {
+               if (ast_test_flag(&flags, OPTION_ALL)) {
                        /* CAPI is set up like CAPI[foo/bar]/clcnt */ 
                        if (!strcmp(c->tech->type, "CAPI")) 
-                               cut = strrchr(name,'/');
+                               cut = strrchr(name, '/');
                        /* Basically everything else is Foo/Bar-Z */
                        else
-                               cut = strchr(name,'-');
+                               cut = strchr(name, '-');
                        /* Get rid of what we've cut */
                        if (cut)
                                *cut = 0;
                }
-               if (!strcasecmp(name, match)) {
-                       ast_log(LOG_WARNING, "Soft hanging %s up.\n",c->name);
+               if (!strcasecmp(name, args.channel)) {
+                       ast_log(LOG_WARNING, "Soft hanging %s up.\n", c->name);
                        ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
-                       if(!all)
+                       if (!ast_test_flag(&flags, OPTION_ALL)) {
+                               ast_channel_unlock(c);
                                break;
+                       }
                }
-               c = ast_channel_walk_locked(c);
+               ast_channel_unlock(c);
        }
-       
-       ast_module_user_remove(u);
 
        return 0;
 }