mini-at/src/mini-atd/main.c

149 lines
3.4 KiB
C

/* mini-at/src/mini-atd/main.c
*
* (c)2006, Laurence Withers, <l@lwithers.me.uk>.
* Released under the GNU GPLv2. See file COPYING or
* http://www.gnu.org/copyleft/gpl.html for details.
*/
void version(void)
{
printf("mini-atd " VERSION "\n"
"(c)2006, Laurence Withers.\n");
}
void usage(void)
{
printf("Usage:\n\n"
" mini-atd [options]\n\n"
"Options:\n"
"-h, --help Display this screen.\n"
"-V, --version Display version.\n"
"-D, --daemon Daemonise.\n"
"-s, --socket Name of socket file (default: ~/.mini-atd).\n"
"-p, --permissions Octal permissions of socket (default: 0600).\n"
"\n");
}
struct option options[] = {
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'V' },
{ "daemon", no_argument, 0, 'D' },
{ "socket", required_argument, 0, 's' },
{ "permissions", required_argument, 0, 'p' },
{ 0, 0, 0, 0 }
};
int main(int argc, char* argv[])
{
const char* socket = 0;
char* endp;
int perms = -1, daemon = 0, fd = -1;
char fn_buf[sizeof(struct sockaddr_un) - sizeof(int)]; // not perfect, but solves build errors
struct time_db tdb;
// process commandline options
while(1) {
switch(getopt_long(argc, argv, "hVDs:p:", options, 0)) {
case -1:
goto done;
case 'h':
usage();
return 0;
case 'V':
version();
return 0;
case 'D':
daemon++;
break;
case 's':
if(socket) {
fprintf(stderr, "Cannot specify name of socket twice.\n");
return 1;
}
socket = optarg;
break;
case 'p':
if(perms != -1) {
fprintf(stderr, "Cannot specify permissions twice.\n");
return 1;
}
endp = 0;
errno = 0;
perms = strtol(optarg, &endp, 8);
if(errno || !endp || *endp) {
fprintf(stderr, "Invalid mode string `%s'.\n", optarg);
return 1;
}
if(perms < 0 || perms > 03777) {
fprintf(stderr, "Invalid mode %04o.\n", perms);
return 1;
}
break;
default:
// getopt() already printed an error message
return -1;
}
}
done:
// defaults if not specified
if(!socket) {
endp = getenv("HOME");
if(!endp) {
fprintf(stderr, "${HOME} not set; cannot construct socket filename.\n");
return 1;
}
snprintf(fn_buf, sizeof(fn_buf) - 1, "%s/.mini-atd", endp);
fn_buf[sizeof(fn_buf) - 1] = 0;
} else {
strncpy(fn_buf, socket, sizeof(fn_buf) - 1);
fn_buf[sizeof(fn_buf) - 1] = 0;
}
if(perms == -1) perms = 0600;
// setup
if(daemon && daemonise()) return 1;
setup_signals();
fd = setup_socket(fn_buf, perms);
if(fd == -1) return 1;
memset(&tdb, 0, sizeof(tdb));
_debug_time_db = &tdb;
// process
while(!Quit) {
if(process_socket(fd, &tdb)) return 1;
process_time_db(&tdb);
sleep(1);
}
// clean up
close(fd);
unlink(fn_buf);
// done
return 0;
}
/* options for text editors
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
vim: expandtab:ts=4:sw=4
*/