Exemplo n.º 1
0
static void stop()
{
FILE	*f;
unsigned long pid;
int	fd;

	if ((f=fopen(PIDFILE, "r")) == 0)	return;
	if (fscanf(f, "%lu", &pid) <= 0)
	{
		fclose(f);
		return;
	}
	fclose(f);

	kill (pid, SIGTERM);

	/*
	** Wait until the daemon goes away by attempting to lock the lock file
	** ourselves.
	*/

	alarm(15);
	fd=open(LOCKFILE, O_RDWR);
	if (fd < 0)	return;
	ll_lock_ex(fd);
	close(fd);
}
Exemplo n.º 2
0
static void stop1(const char *lockfile, const char *pidfile)
{
int	lockfd;
pid_t	p;

	if ((lockfd=open(lockfile, O_RDWR|O_CREAT, 0600)) < 0)
	{
		perror(lockfile);
		exit(1);
	}

	if ( ll_lock_ex_test(lockfd) == 0)	/* No daemon process running */
	{
		close(lockfd);
		exit (0);	/* That was easy! */
	}

	signal(SIGCHLD, sigexit);

	if ((p=fork()) == -1)
	{
		perror("fork");
		exit(1);
	}

	if (p)	/* Parent - first sends a SIGTERM, then a SIGKILL */
	{
	int	signum=SIGTERM;

		close(lockfd);
		for (;; sleep(10))
		{
		FILE	*fp;
		int	c;

			if ((fp=fopen(pidfile, "r")) == NULL)
				continue;

			p=0;

			while ((c=getc(fp)) != EOF && c != '\n')
			{
				if (isdigit(c))
					p=p*10+(c-'0');
			}

			fclose(fp);
			if (p)
				kill(p, signum);
			signum=SIGKILL;
		}
	}

	if (ll_lock_ex(lockfd))
		perror("lock");
	close(lockfd);
	exit(0);
}
Exemplo n.º 3
0
static FILE *open_and_lock_cached_policy_file(const char *filename,
					      int *readwrite)
{
	int fd;
	int save_errno;

	*readwrite=1;
	fd=open(filename, O_RDWR | O_CREAT, 0644);

	if (fd >= 0 && ll_lock_ex(fd) >= 0)
	{
		FILE *fp=fdopen(fd, "r+");

		if (fp)
			return fp;
	}

	/*
	** Non-root will not be able to write to the cache.
	**
	** Do not pollute terminal output, but if this is run from the
	** script let's bark this somewhere where someone will hopefully
	** notice this.
	*/
	save_errno=errno;
	if (!isatty(2))
	{
		errno=save_errno;
		perror(filename);
	}
	if (fd >= 0)
		close(fd);

	*readwrite=0;
	fd=open(filename, O_RDONLY);

	if (fd >= 0 && ll_lockfd(fd, ll_readlock|ll_whence_start|ll_wait,
				 0, 0) >= 0)
	{
		FILE *fp=fdopen(fd, "r");

		if (fp)
			return fp;
	}

	if (fd >= 0)
		close(fd);
	return NULL;
}
Exemplo n.º 4
0
static void check_db()
{
	char *dbname;
	char *lockname;
	int lockfd;
	struct dbobj db;
	time_t now;
	char *sender_key, *p;

	size_t val_len;
	char *val;

	if (!dbfile || !*dbfile)
		return;

	sender_key=strdup(sender);
	dbname=malloc(strlen(dbfile)+ sizeof( "." DBNAME));
	lockname=malloc(strlen(dbfile)+ sizeof(".lock"));

	for (p=sender_key; *p; p++)
		*p=tolower((int)(unsigned char)*p);

	if (!dbname || !lockname || !sender)
	{
		perror("malloc");
		exit(EX_TEMPFAIL);
	}

	strcat(strcpy(dbname, dbfile), "." DBNAME);
	strcat(strcpy(lockname, dbfile), ".lock");

	lockfd=open(lockname, O_RDWR|O_CREAT, 0666);

	if (lockfd < 0 || ll_lock_ex(lockfd))
	{
		perror(lockname);
		exit(EX_TEMPFAIL);
	}

	dbobj_init(&db);

	if (dbobj_open(&db, dbname, "C") < 0)
	{
		perror(dbname);
		exit(EX_TEMPFAIL);
	}

	time(&now);

	val=dbobj_fetch(&db, sender_key, strlen(sender_key), &val_len, "");

	if (val)
	{
		time_t t;

		if (val_len >= sizeof(t))
		{
			memcpy(&t, val, sizeof(t));

			if (t >= now - interval * 60 * 60 * 24)
			{
				free(val);
				dbobj_close(&db);
				close(lockfd);
				exit(0);
			}
		}
		free(val);
	}

	dbobj_store(&db, sender_key, strlen(sender_key),
		    (void *)&now, sizeof(now), "R");
	dbobj_close(&db);
	close(lockfd);
}
Exemplo n.º 5
0
int main(int argc, char **argv)
{
    if (argc > 1 && strcmp(argv[1], "--version") == 0)
    {
        printf("%s\n", COURIER_COPYRIGHT);
        exit(0);
    }

    if (chdir(courierdir()))
    {
        perror("chdir");
        return (1);
    }
    if (argc < 2)	return (0);

    if (strcmp(argv[1], "stop") == 0)
    {
        int	fd;

        trigger(TRIGGER_STOP);

        /* Wait until the exclusive lock goes away: */

        signal(SIGHUP, SIG_DFL);
        if ((fd=open(TMPDIR "/courierd.lock", O_RDWR|O_CREAT, 0600))
                < 0)	clog_msg_errno();

        alarm(15);	/* But abort after 15 seconds. */

        ll_lock_ex(fd);
        return (0);
    }

    if (strcmp(argv[1], "restart") == 0)
    {
        trigger(TRIGGER_RESTART);
        return (0);
    }

    if (strcmp(argv[1], "flush") == 0)
    {
        ino_t	n;
        struct	ctlfile	ctf;

        if (getuid())
        {
            /*
            ** We'll fail trying to open the pipe anyway, but let's
            ** give a meaningful error message now.
            */
            fprintf(stderr,
                    "courier flush can be executed only by the superuser.\n");
            exit(1);
        }

        if (argc < 3)
        {
            trigger(TRIGGER_FLUSH);	/* Everything */
            exit(0);
        }

        if (comparseqid(argv[2], &n) == 0 &&
                ctlfile_openi(n, &ctf, 1) == 0)
        {
            int c=ctlfile_searchfirst(&ctf, COMCTLFILE_MSGID);

            if (c >= 0 && strcmp(ctf.lines[c]+1, argv[2]) == 0)
            {
                char	*s=courier_malloc(sizeof(TRIGGER_FLUSHMSG)+1+
                                          strlen(argv[2]));

                strcat(strcat(strcpy(s, TRIGGER_FLUSHMSG),
                              argv[2]), "\n");
                trigger(s);
                ctlfile_close(&ctf);
                return (0);
            }
            ctlfile_close(&ctf);
        }
        fprintf(stderr, "No such message.\n");
        exit(1);
        return (1);
    }

    /* Might as well... */

    if (strcmp(argv[1], "start") == 0)
    {
        pid_t	p;
        int	waitstat;
        char	dummy;

        /*
        ** Ok, courierd will close file descriptor 3 when it starts, so we
        ** put a pipe on there, and wait for it to close.
        */
        int	pipefd[2];

        close(3);
        if (open("/dev/null", O_RDONLY) != 3 || pipe(pipefd))
        {
            fprintf(stderr, "Cannot open pipe\n");
            exit(1);
        }

        if (getuid())
        {
            /*
            ** We'll fail trying to execute courierd anyway, but let's
            ** give a meaningful error message now.
            */
            fprintf(stderr, "courier start can be executed only by the superuser.\n");
            return (1);
        }
        signal(SIGCHLD, SIG_DFL);
        while ((p=fork()) == -1)
        {
            perror("fork");
            sleep(10);
        }
        if (p == 0)
        {
            dup2(pipefd[1], 3);
            close(pipefd[1]);
            close(pipefd[0]);
            while ((p=fork()) == -1)
            {
                perror("fork");
                sleep(10);
            }
            if (p == 0)
            {
                /*
                ** stdin from the bitbucket.  stdout to
                ** /dev/null, or the bitbucket.
                */

                signal(SIGHUP, SIG_IGN);
                close(0);
                open("/dev/null", O_RDWR);
                dup2(0, 1);
                dup2(0, 2);
                /* See if we can disconnect from the terminal */

#ifdef	TIOCNOTTY
                {
                    int fd=open("/dev/tty", O_RDWR);

                    if (fd >= 0)
                    {
                        ioctl(fd, TIOCNOTTY, 0);
                        close(fd);
                    }
                }
#endif
                /* Remove any process groups */

#if	HAVE_SETPGRP
#if	SETPGRP_VOID
                setpgrp();
#else
                setpgrp(0, 0);
#endif
#endif
                execl( DATADIR "/courierctl.start",
                       "courierctl.start", (char *)0);
                perror("exec");
                _exit(1);
            }
            _exit(0);
        }
        close(pipefd[1]);
        while (wait(&waitstat) != p)
            ;
        if (read(pipefd[0], &dummy, 1) < 0)
            ; /* ignore */
        close(pipefd[0]);
        close(3);
        return (0);
    }

    if (strcmp(argv[1], "clear") == 0 && argc > 2)
    {
        libmail_changeuidgid(MAILUID, MAILGID);

        if (strcmp(argv[2], "all") == 0)
        {
            courier_clear_all();
        }
        else
        {
            track_save(argv[2], TRACK_ADDRACCEPTED);
            printf("%s cleared.\n", argv[2]);
        }
        return (0);
    }

    if (argc > 2 && strcmp(argv[1], "show") == 0 &&
            strcmp(argv[2], "all") == 0)
    {
        libmail_changeuidgid(MAILUID, MAILGID);
        courier_show_all();
    }

    return (0);
}