e6a762ad7b53dd1686a55e6906bcc1345e125f5e
[expresskeys.git] / src-expresskeys / command_line.c
1 /*
2  expresskeys - Support ExpressKeys, Touch Strips, Scroll Wheel on Wacom tablets.
3
4  Copyright (C) 2005-2007 - Mats Johannesson
5
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15
16  You should have received a copy of the GNU General Public License along
17  with this program; if not, write to the Free Software Foundation, Inc.,
18  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include <stdio.h> /* NULL, fprintf */
22 #include <string.h> /* strlen, strstr */
23 #include <ctype.h> /* tolower */
24 #include <sys/types.h> /* kill */
25 #include <signal.h> /* kill */
26
27 #include "defines.h"
28
29 /* Globals: */
30
31 /* Behaviour flags: */
32 int go_daemon;
33 int be_verbose;
34 int just_exit;
35 /* Kill a daemon instance: */
36 int send_sigterm;
37 /* Reread configuration files of a daemon instance: */
38 int send_sigusr1;
39 /* Report status of a daemon instance to file/screen: */
40 int send_sigusr2;
41
42 /* Our version. Remember to change it: */
43 const char* our_prog_version = "0.4.1";
44
45 /* Generic strings used in comparisons,
46  and for flow control in some functions: */
47 const char* pad_string = "pad";
48 const char* stylus_string = "stylus";
49
50 /* Pad and styli named on the command line: */
51 const char* user_pad;
52 const char* user_stylus1;
53 const char* user_stylus2;
54
55 /* Externals: */
56
57 extern int live_pid;
58 extern const char* our_prog_name;
59
60 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
61  Command line errors or an explicit -h prints a help screen:
62  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
63
64 static void print_help(FILE* errorfp)
65 {
66         const char* help_page =
67 "[OPTION]... [DEVICE]...\n"
68 "Any combination of pad and/or stylus can be specified.\n"
69 "An empty command line means automatic device search.\n"
70 "Options can be written like -dv or -d --v in any place.\n\n"
71
72 "  -d makes the program a daemon (runs in the background).\n"
73 "  -k terminates (kills) an already running daemon instance.\n"
74 "  -r re-reads the configuration files of a running daemon.\n"
75 "  -s tells a daemon instance to report status (file/screen).\n"
76 "  -v prints info to the screen at many execution points.\n"
77 "  -x sets -v and exits after some important info blocks.\n"
78 "  -h unconditionally brings up this help text.\n\n"
79
80 "Example1: expresskeys -d (All 'pad's and/or 'stylus'es found get used)\n"
81 "Example2: expresskeys 1stIntuos3Pad 1stIntuos3Stylus2 -d (named devices)\n"
82 "Example3: expresskeys -rv (visibly re-read the configuration file)\n\n"
83
84 "Please direct any bug reports or questions to the top address\n"
85 "in the AUTHORS file. This program is _not_ a linuxwacom project.\n";
86
87         fprintf(stderr, "expresskeys Version: %s\n\n", our_prog_version);
88
89         fprintf(stderr, "Usage: %s %s", our_prog_name, help_page);
90
91         exit_on_error(errorfp, "", "", "");
92
93 }
94
95 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
96  Parse command line for behaviour flags and named devices:
97  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
98
99 void parse_command(FILE* errorfp, int argc, char* argv[])
100 {
101         char write_buffer[MAXBUFFER];
102
103         int give_help = 0;
104         int invalid = 0;
105         int cosmetic;
106         int i, c;
107
108         while ((--argc > 0) && (**++argv == '-' || **argv != '-')) {
109                 if (**argv == '-') {
110                         cosmetic = 0;
111                         while (((c = *++argv[0])) && (argc != NON_VALID)) {
112                                 switch (c) {
113                                         case '-':
114                                         cosmetic++;
115                                         if (cosmetic > 1) {
116                                                 fprintf(stderr,
117 "\n%s ERROR: Only '-' or '--' before the switch(es), please.\n", our_prog_name);
118                                                 argc = NON_VALID;
119                                                 invalid = 1;
120                                         }
121                                         case 'd':
122                                         go_daemon = 1;
123                                         break;
124
125                                         case 'k':
126                                         send_sigterm = 1;
127                                         break;
128
129                                         case 'r':
130                                         send_sigusr1 = 1;
131                                         break;
132
133                                         case 's':
134                                         send_sigusr2 = 1;
135                                         break;
136
137                                         case 'v':
138                                         be_verbose = 1;
139                                         break;
140
141                                         case 'x':
142                                         just_exit = 1;
143                                         be_verbose = 1;
144                                         break;
145
146                                         case 'h':
147                                         give_help = 1;
148                                         break;
149
150                                         default:
151                                         fprintf(stderr,
152         "\n%s ERROR: Invalid switch '%c' on command line.\n", our_prog_name, c);
153                                         argc = NON_VALID;
154                                         invalid = 1;
155                                         break;
156                                 }
157                         }
158                 } else {
159                         if (strlen(argv[0]) < MAXBUFFER) {
160                                 i = 0;
161                                 do {
162                                         write_buffer[i] = tolower(argv[0][i]);
163                                 } while(argv[0][i++] != '\0');
164                                 write_buffer[i-1] = '\0';
165                         } else {
166                                 exit_on_error(errorfp,
167 "\n%s ERROR: A device name on the command line was too long to handle!\n",
168                                                         our_prog_name, "");
169                         }
170
171                         if (((strstr(write_buffer, pad_string)) !=NULL)
172                                                 && (!user_pad)) {
173                                 user_pad = *argv;
174                         } else if (((strstr(write_buffer, stylus_string))!=NULL)
175                                                 && (!user_stylus1)) {
176                                 user_stylus1 = *argv;
177                         } else if (((strstr(write_buffer, stylus_string))!=NULL)
178                                                 && (!user_stylus2)) {
179                                 user_stylus2 = *argv;
180                         } else {
181                                 invalid = 1;
182                         }
183
184                         if (invalid) {
185                                 fprintf(stderr,
186                 "\n%s ERROR: Invalid or extra device '%s' on command line.\n",
187                                                 our_prog_name, write_buffer);
188                                 argc = NON_VALID;
189                         }
190                 }
191         }
192
193         if ((argc != 0) || (give_help == 1)) {
194                 if (!invalid) {
195                         fprintf(stderr, "\n");
196                 }
197                 print_help(errorfp);
198         }
199
200 }
201
202 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
203  Act on user flags to kill, show status or reread configuration files of daemon:
204  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
205
206 void send_command(FILE* errorfp)
207 {
208         if (send_sigusr1) {
209                 if ((kill(live_pid, SIGUSR1)) != NON_VALID) {
210                         if (be_verbose) {
211                                 exit_on_error(errorfp,
212 "\n%s SUCCESS: The expresskeys configuration files has been re-read\n",
213                                                 our_prog_name, "");
214                         }
215                         exit_on_error(errorfp, "", "", "");
216                 } else {
217                         exit_on_error(errorfp,
218 "\n%s FAILURE: The expresskeys configuration files could not be re-read!\n",
219                                                 our_prog_name, "");
220                 }
221         }
222         if (send_sigusr2) {
223                 if ((kill(live_pid, SIGUSR2)) != NON_VALID) {
224                         if (be_verbose) {
225                                 exit_on_error(errorfp,
226 "\n%s SUCCESS: The expresskeys status has been reported\n",
227                                                 our_prog_name, "");
228                         }
229                         exit_on_error(errorfp, "", "", "");
230                 } else {
231                         exit_on_error(errorfp,
232 "\n%s FAILURE: The expresskeys status could not be reported!\n",
233                                                 our_prog_name, "");
234                 }
235         }
236         if (send_sigterm) {
237                 if ((kill(live_pid, SIGTERM)) != NON_VALID) {
238                         if (be_verbose) {
239                                 exit_on_error(errorfp,
240 "\n%s SUCCESS: The expresskeys daemon has been terminated\n",
241                                                 our_prog_name, "");
242                         }
243                         exit_on_error(errorfp, "", "", "");
244                 } else {
245                         exit_on_error(errorfp,
246 "\n%s FAILURE: The expresskeys daemon could not be terminated!\n",
247                                                 our_prog_name, "");
248                 }
249         }
250         exit_on_error(errorfp, "\n%s FAILURE: UNKNOWN COMMAND!\n",
251                                                 our_prog_name, "");
252
253 }
254
255 /* End Code */
256