formatting cleanup on the header,
[asterisk/asterisk.git] / apps / app_softhangup.c
old mode 100755 (executable)
new mode 100644 (file)
index 804a392..7af8525
 /*! \file
  *
  * \brief SoftHangup application
+ *
+ * \author Mark Spencer <markster@digium.com>
  * 
  * \ingroup applications
  */
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-
 #include "asterisk.h"
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #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 *tdesc = "Hangs up the requested channel";
-
-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";
 
-STANDARD_LOCAL_USER;
+enum {
+       OPTION_ALL = (1 << 0),
+};
 
-LOCAL_USER_DECL;
+AST_APP_OPTIONS(app_opts,{
+       AST_APP_OPTION('a', OPTION_ALL),
+});
 
 static int softhangup_exec(struct ast_channel *chan, void *data)
 {
-       struct localuser *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;
        }
-       
-       LOCAL_USER_ADD(u);
-
-       cdata = ast_strdupa(data);
-       match = strsep(&cdata, "|");
-       options = strsep(&cdata, "|");
-       all = options && strchr(options,'a');
-       c = ast_channel_walk_locked(NULL);
-       while (c) {
-               strncpy(name, c->name, sizeof(name)-1);
-               ast_mutex_unlock(&c->lock);
-               /* XXX watch out, i think it is wrong to access c-> after unlocking! */
-               if (all) {
+
+       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));
+               if (ast_test_flag(&flags, OPTION_ALL)) {
                        /* CAPI is set up like CAPI[foo/bar]/clcnt */ 
-                       if (!strcmp(c->type,"CAPI")) 
-                               cut = strrchr(name,'/');
+                       if (!strcmp(c->tech->type, "CAPI")) 
+                               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);
        }
-       
-       LOCAL_USER_REMOVE(u);
 
        return 0;
 }
 
-int unload_module(void)
+static int unload_module(void)
 {
-       int res;
-
-       res = ast_unregister_application(app);
-
-       STANDARD_HANGUP_LOCALUSERS;
-
-       return res;     
+       return ast_unregister_application(app);
 }
 
-int load_module(void)
+static int load_module(void)
 {
        return ast_register_application(app, softhangup_exec, synopsis, desc);
 }
 
-char *description(void)
-{
-       return tdesc;
-}
-
-int usecount(void)
-{
-       int res;
-       STANDARD_USECOUNT(res);
-       return res;
-}
-
-char *key()
-{
-       return ASTERISK_GPL_KEY;
-}
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Hangs up the requested channel");