the last round of file version tags
[asterisk/asterisk.git] / apps / app_softhangup.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * SoftHangup application
5  * 
6  * Copyright (C) 1999, Mark Spencer
7  *
8  * Mark Spencer <markster@linux-support.net>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
14 #include <sys/types.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17 #include <string.h>
18
19 #include "asterisk.h"
20
21 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
22
23 #include "asterisk/file.h"
24 #include "asterisk/logger.h"
25 #include "asterisk/channel.h"
26 #include "asterisk/pbx.h"
27 #include "asterisk/module.h"
28 #include "asterisk/lock.h"
29
30 static char *synopsis = "Soft Hangup Application";
31
32 static char *tdesc = "Hangs up the requested channel";
33
34 static char *desc = "  SoftHangup(Technology/resource|options)\n"
35 "Hangs up the requested channel.  Always returns 0\n"
36 "- 'options' may contain the following letter:\n"
37 "     'a' : hang up all channels on a specified device instead of a single resource\n";
38
39 static char *app = "SoftHangup";
40
41 STANDARD_LOCAL_USER;
42
43 LOCAL_USER_DECL;
44
45 static int softhangup_exec(struct ast_channel *chan, void *data)
46 {
47         struct localuser *u;
48         struct ast_channel *c=NULL;
49         char *options, *cut, *cdata, *match;
50         char name[AST_CHANNEL_NAME] = "";
51         int all = 0;
52
53         if (!data) {
54                 ast_log(LOG_WARNING, "SoftHangup requires an argument (Technology/resource)\n");
55                 return 0;
56         }
57         
58         cdata = ast_strdupa(data);
59         match = strsep(&cdata, "|");
60         options = strsep(&cdata, "|");
61         all = options && strchr(options,'a');
62         LOCAL_USER_ADD(u);
63         c = ast_channel_walk_locked(NULL);
64         while (c) {
65                 strncpy(name, c->name, sizeof(name)-1);
66                 ast_mutex_unlock(&c->lock);
67                 /* XXX watch out, i think it is wrong to access c-> after unlocking! */
68                 if (all) {
69                         /* CAPI is set up like CAPI[foo/bar]/clcnt */ 
70                         if (!strcmp(c->type,"CAPI")) 
71                                 cut = strrchr(name,'/');
72                         /* Basically everything else is Foo/Bar-Z */
73                         else
74                                 cut = strchr(name,'-');
75                         /* Get rid of what we've cut */
76                         if (cut)
77                                 *cut = 0;
78                 }
79                 if (!strcasecmp(name, match)) {
80                         ast_log(LOG_WARNING, "Soft hanging %s up.\n",c->name);
81                         ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
82                         if(!all)
83                                 break;
84                 }
85                 c = ast_channel_walk_locked(c);
86         }
87         LOCAL_USER_REMOVE(u);
88
89         return 0;
90 }
91
92 int unload_module(void)
93 {
94         STANDARD_HANGUP_LOCALUSERS;
95         return ast_unregister_application(app);
96 }
97
98 int load_module(void)
99 {
100         return ast_register_application(app, softhangup_exec, synopsis, desc);
101 }
102
103 char *description(void)
104 {
105         return tdesc;
106 }
107
108 int usecount(void)
109 {
110         int res;
111         STANDARD_USECOUNT(res);
112         return res;
113 }
114
115 char *key()
116 {
117         return ASTERISK_GPL_KEY;
118 }