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
 /*! \file
  *
  * \brief SoftHangup application
+ *
+ * \author Mark Spencer <markster@digium.com>
  * 
  * \ingroup applications
  */
 
  * 
  * \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.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/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 *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"
 "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";
 
 
 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)
 {
 
 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)) {
        
        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;
        }
                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 */ 
                        /* 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
                        /* 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;
                }
                        /* 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);
                        ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
-                       if(!all)
+                       if (!ast_test_flag(&flags, OPTION_ALL)) {
+                               ast_channel_unlock(c);
                                break;
                                break;
+                       }
                }
                }
-               c = ast_channel_walk_locked(c);
+               ast_channel_unlock(c);
        }
        }
-       
-       LOCAL_USER_REMOVE(u);
 
        return 0;
 }
 
 
        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);
 }
 
 {
        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");