149 lines
3.4 KiB
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
|
|
*/
|