dgamelaunch/dgl-wall.c

129 lines
2.5 KiB
C

/* dgl-wall sends a message to all logged in users. If you specified a
* configuration file to dgamelaunch, you must do so as well for dgl-wall,
* or else the message won't be sent. */
#include <fcntl.h>
#include <dirent.h>
#include <pwd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include "dgamelaunch.h"
int
main (int argc, char** argv)
{
int c, i, len;
char buf[82], *ptr = buf, *from = NULL;
struct dg_game ** games = NULL;
struct flock fl = { 0 };
struct passwd* pw = getpwuid(getuid());
FILE* spool = NULL;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
*ptr = '\0';
while ((c = getopt(argc, argv, "f:F:")) != -1)
{
switch (c)
{
case 'f':
config = strdup(optarg);
break;
case 'F':
from = strdup(optarg);
break;
default:
goto usage;
}
}
if (from == NULL)
from = pw->pw_name;
while (optind < argc)
{
if (strlen(buf) != 0)
strlcat (buf, " ", sizeof(buf));
strlcat (buf, argv[optind++], sizeof(buf));
}
if (strlen(buf) > 80)
{
fprintf(stderr, "Error: Message is too long! (80 chars max)\n");
return 1;
}
if (strlen(buf) == 0)
{
usage:
fprintf(stderr, "Usage: %s [-f config] [-F fromname] message\n", argv[0]);
return 1;
}
create_config();
if (chroot (myconfig->chroot))
{
perror("Couldn't change root directory");
return 1;
}
if (chdir ("/"))
{
perror("Couldn't chdir to root directory");
return 1;
}
games = populate_games (&len);
if (len == 0)
{
fprintf(stderr, "Error: no one's logged in!\n");
return 1;
}
for (i = 0; i < len; i++)
{
char* fname = NULL;
size_t len;
len = strlen(myconfig->spool) + strlen(games[i]->name) + 2;
fname = malloc (len + 1);
snprintf(fname, len, "%s/%s", myconfig->spool, games[i]->name);
if ((spool = fopen(fname, "a")) == NULL)
{
fprintf (stderr, "Warning: couldn't open mailbox for %s.\n", games[i]->name);
free (fname);
continue;
}
while (fcntl (fileno(spool), F_SETLK, &fl) == -1)
{
if (errno != EAGAIN)
fprintf (stderr, "Warning: fcntl errored out trying to lock mailbox for %s\n",
games[i]->name);
sleep(1);
}
/* Now that we have the lock, begin the write */
fprintf(spool, "%s:%s\n", from, buf);
fclose(spool);
free(fname);
}
puts("Message sent successfully.");
return 0;
}