コード例 #1
0
int
cmd_lock_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx)
{
	server_lock();

	return (0);
}
コード例 #2
0
ファイル: cmd-lock-server.c プロジェクト: east11210/tmux
static enum cmd_retval
cmd_lock_server_exec(struct cmd *self, __unused struct cmd_q *cmdq)
{
	if (self->entry == &cmd_lock_server_entry)
		server_lock();
	else if (self->entry == &cmd_lock_session_entry)
		server_lock_session(cmdq->state.tflag.s);
	else
		server_lock_client(cmdq->state.c);

	recalculate_sizes();

	return (CMD_RETURN_NORMAL);
}
コード例 #3
0
ファイル: cmd-lock-server.c プロジェクト: FauxFaux/tmux
enum cmd_retval
cmd_lock_server_exec(struct cmd *self, unused struct cmd_q *cmdq)
{
	struct args	*args = self->args;
	struct client	*c;
	struct session	*s;

	if (self->entry == &cmd_lock_server_entry)
		server_lock();
	else if (self->entry == &cmd_lock_session_entry) {
		s = cmd_find_session(cmdq, args_get(args, 't'), 0);
		if (s == NULL)
			return (CMD_RETURN_ERROR);
		server_lock_session(s);
	} else {
		c = cmd_find_client(cmdq, args_get(args, 't'), 0);
		if (c == NULL)
			return (CMD_RETURN_ERROR);
		server_lock_client(c);
	}
	recalculate_sizes();

	return (CMD_RETURN_NORMAL);
}
コード例 #4
0
ファイル: cnid_metad.c プロジェクト: okket/netatalk
/* ------------------ */
int main(int argc, char *argv[])
{
    char  volpath[MAXPATHLEN + 1];
    int   len, actual_len;
    pid_t pid;
    int   status;
    char  *dbdpn = _PATH_CNID_DBD;
    char  *host = DEFAULTHOST;
    char  *port = DEFAULTPORT;
    int    i;
    int    cc;
    uid_t  uid = 0;
    gid_t  gid = 0;
    int    err = 0;
    int    debug = 0;
    int    ret;
    char   *loglevel = NULL;
    char   *logfile  = NULL;
    sigset_t set;
    struct volinfo *volinfo;

    set_processname("cnid_metad");

    while (( cc = getopt( argc, argv, "ds:p:h:u:g:l:f:")) != -1 ) {
        switch (cc) {
        case 'd':
            debug = 1;
            break;
        case 'h':
            host = strdup(optarg);
            break;
        case 'u':
            uid = user_to_uid (optarg);
            if (!uid) {
                LOG(log_error, logtype_cnid, "main: bad user %s", optarg);
                err++;
            }
            break;
        case 'g':
            gid =group_to_gid (optarg);
            if (!gid) {
                LOG(log_error, logtype_cnid, "main: bad group %s", optarg);
                err++;
            }
            break;
        case 'p':
            port = strdup(optarg);
            break;
        case 's':
            dbdpn = strdup(optarg);
            break;
        case 'l':
            loglevel = strdup(optarg);
            break;
        case 'f':
            logfile = strdup(optarg);
            break;
        default:
            err++;
            break;
        }
    }

    if (loglevel) {
        strlcpy(logconfig + 8, loglevel, 13);
        free(loglevel);
        strcat(logconfig, " ");
    }
    if (logfile) {
        strlcat(logconfig, logfile, MAXPATHLEN);
        free(logfile);
    }
    setuplog(logconfig);

    if (err) {
        LOG(log_error, logtype_cnid, "main: bad arguments");
        daemon_exit(1);
    }

    /* Check PID lockfile and become a daemon */
    switch(server_lock("cnid_metad", _PATH_CNID_METAD_LOCK, debug)) {
    case -1: /* error */
        daemon_exit(EXITERR_SYS);
    case 0: /* child */
        break;
    default: /* server */
        exit(0);
    }

    if ((srvfd = tsockfd_create(host, port, 10)) < 0)
        daemon_exit(1);

    /* switch uid/gid */
    if (uid || gid) {
        LOG(log_debug, logtype_cnid, "Setting uid/gid to %i/%i", uid, gid);
        if (gid) {
            if (SWITCH_TO_GID(gid) < 0) {
                LOG(log_info, logtype_cnid, "unable to switch to group %d", gid);
                daemon_exit(1);
            }
        }
        if (uid) {
            if (SWITCH_TO_UID(uid) < 0) {
                LOG(log_info, logtype_cnid, "unable to switch to user %d", uid);
                daemon_exit(1);
            }
        }
    }

    set_signal();

    sigemptyset(&set);
    sigprocmask(SIG_SETMASK, NULL, &set);
    sigdelset(&set, SIGCHLD);

    while (1) {
        rqstfd = usockfd_check(srvfd, &set);
        /* Collect zombie processes and log what happened to them */
        if (sigchild) while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
            for (i = 0; i < MAXVOLS; i++) {
                if (srv[i].pid == pid) {
                    srv[i].pid = 0;
                    close(srv[i].control_fd);
                    break;
                }
            }
            if (WIFEXITED(status)) {
                LOG(log_info, logtype_cnid, "cnid_dbd pid %i exited with exit code %i",
                    pid, WEXITSTATUS(status));
            }
            else if (WIFSIGNALED(status)) {
                LOG(log_info, logtype_cnid, "cnid_dbd pid %i exited with signal %i",
                    pid, WTERMSIG(status));
            }
            sigchild = 0;
        }
        if (rqstfd <= 0)
            continue;

        ret = readt(rqstfd, &len, sizeof(int), 1, 4);

        if (!ret) {
            /* already close */
            goto loop_end;
        }
        else if (ret < 0) {
            LOG(log_severe, logtype_cnid, "error read: %s", strerror(errno));
            goto loop_end;
        }
        else if (ret != sizeof(int)) {
            LOG(log_error, logtype_cnid, "short read: got %d", ret);
            goto loop_end;
        }
        /*
         *  checks for buffer overruns. The client libatalk side does it too
         *  before handing the dir path over but who trusts clients?
         */
        if (!len || len +DBHOMELEN +2 > MAXPATHLEN) {
            LOG(log_error, logtype_cnid, "wrong len parameter: %d", len);
            goto loop_end;
        }

        actual_len = readt(rqstfd, volpath, len, 1, 5);
        if (actual_len < 0) {
            LOG(log_severe, logtype_cnid, "Read(2) error : %s", strerror(errno));
            goto loop_end;
        }
        if (actual_len != len) {
            LOG(log_error, logtype_cnid, "error/short read (dir): %s", strerror(errno));
            goto loop_end;
        }
        volpath[len] = '\0';

        /* Load .volinfo file */
        if ((volinfo = allocvolinfo(volpath)) == NULL) {
            LOG(log_severe, logtype_cnid, "allocvolinfo(\"%s\"): %s",
                volpath, strerror(errno));
            goto loop_end;
        }

        if (set_dbdir(volinfo->v_dbpath) < 0) {
            goto loop_end;
        }

        maybe_start_dbd(dbdpn, volinfo);

        (void)closevolinfo(volinfo);

    loop_end:
        close(rqstfd);
    }
}
コード例 #5
0
ファイル: main.c プロジェクト: jrmithdobbs/netatalk-2-2-0-p6
int main(int ac, char **av)
{
    AFPConfig           *config;
    fd_set              rfds;
    void                *ipc;
    struct sigaction	sv;
    sigset_t            sigs;
    int                 ret;

#ifdef TRU64
    argc = ac;
    argv = av;
    set_auth_parameters( ac, av );
#endif /* TRU64 */

    /* Log SIGBUS/SIGSEGV SBT */
    fault_setup(NULL);

    /* Default log setup: log to syslog */
    setuplog("default log_note");

    afp_options_init(&default_options);
    if (!afp_options_parse(ac, av, &default_options))
        exit(EXITERR_CONF);

    /* Save the user's current umask for use with CNID (and maybe some 
     * other things, too). */
    default_options.save_mask = umask( default_options.umask );

    switch(server_lock("afpd", default_options.pidfile,
                       default_options.flags & OPTION_DEBUG)) {
    case -1: /* error */
        exit(EXITERR_SYS);
    case 0: /* child */
        break;
    default: /* server */
        exit(0);
    }
    atexit(afp_exit);

    /* install child handler for asp and dsi. we do this before afp_goaway
     * as afp_goaway references stuff from here. 
     * XXX: this should really be setup after the initial connections. */
    if (!(server_children = server_child_alloc(default_options.connections,
                            CHILD_NFORKS))) {
        LOG(log_error, logtype_afpd, "main: server_child alloc: %s", strerror(errno) );
        exit(EXITERR_SYS);
    }

    memset(&sv, 0, sizeof(sv));    
    /* linux at least up to 2.4.22 send a SIGXFZ for vfat fs,
       even if the file is open with O_LARGEFILE ! */
#ifdef SIGXFSZ
    sv.sa_handler = SIG_IGN;
    sigemptyset( &sv.sa_mask );
    if (sigaction(SIGXFSZ, &sv, NULL ) < 0 ) {
        LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
        exit(EXITERR_SYS);
    }
#endif
    
    sv.sa_handler = child_handler;
    sigemptyset( &sv.sa_mask );
    sigaddset(&sv.sa_mask, SIGALRM);
    sigaddset(&sv.sa_mask, SIGHUP);
    sigaddset(&sv.sa_mask, SIGTERM);
    sigaddset(&sv.sa_mask, SIGUSR1);
    sigaddset(&sv.sa_mask, SIGQUIT);    
    sv.sa_flags = SA_RESTART;
    if ( sigaction( SIGCHLD, &sv, NULL ) < 0 ) {
        LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
        exit(EXITERR_SYS);
    }

    sv.sa_handler = afp_goaway;
    sigemptyset( &sv.sa_mask );
    sigaddset(&sv.sa_mask, SIGALRM);
    sigaddset(&sv.sa_mask, SIGTERM);
    sigaddset(&sv.sa_mask, SIGHUP);
    sigaddset(&sv.sa_mask, SIGCHLD);
    sigaddset(&sv.sa_mask, SIGQUIT);
    sv.sa_flags = SA_RESTART;
    if ( sigaction( SIGUSR1, &sv, NULL ) < 0 ) {
        LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
        exit(EXITERR_SYS);
    }

    sigemptyset( &sv.sa_mask );
    sigaddset(&sv.sa_mask, SIGALRM);
    sigaddset(&sv.sa_mask, SIGTERM);
    sigaddset(&sv.sa_mask, SIGUSR1);
    sigaddset(&sv.sa_mask, SIGCHLD);
    sigaddset(&sv.sa_mask, SIGQUIT);
    sv.sa_flags = SA_RESTART;
    if ( sigaction( SIGHUP, &sv, NULL ) < 0 ) {
        LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
        exit(EXITERR_SYS);
    }


    sigemptyset( &sv.sa_mask );
    sigaddset(&sv.sa_mask, SIGALRM);
    sigaddset(&sv.sa_mask, SIGHUP);
    sigaddset(&sv.sa_mask, SIGUSR1);
    sigaddset(&sv.sa_mask, SIGCHLD);
    sigaddset(&sv.sa_mask, SIGQUIT);
    sv.sa_flags = SA_RESTART;
    if ( sigaction( SIGTERM, &sv, NULL ) < 0 ) {
        LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
        exit(EXITERR_SYS);
    }

    sigemptyset( &sv.sa_mask );
    sigaddset(&sv.sa_mask, SIGALRM);
    sigaddset(&sv.sa_mask, SIGHUP);
    sigaddset(&sv.sa_mask, SIGUSR1);
    sigaddset(&sv.sa_mask, SIGCHLD);
    sigaddset(&sv.sa_mask, SIGTERM);
    sv.sa_flags = SA_RESTART;
    if (sigaction(SIGQUIT, &sv, NULL ) < 0 ) {
        LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
        exit(EXITERR_SYS);
    }

    /* afpd.conf: not in config file: lockfile, connections, configfile
     *            preference: command-line provides defaults.
     *                        config file over-writes defaults.
     *
     * we also need to make sure that killing afpd during startup
     * won't leave any lingering registered names around.
     */

    sigemptyset(&sigs);
    sigaddset(&sigs, SIGALRM);
    sigaddset(&sigs, SIGHUP);
    sigaddset(&sigs, SIGUSR1);
#if 0
    /* don't block SIGTERM */
    sigaddset(&sigs, SIGTERM);
#endif
    sigaddset(&sigs, SIGCHLD);

    pthread_sigmask(SIG_BLOCK, &sigs, NULL);
    if (!(configs = configinit(&default_options))) {
        LOG(log_error, logtype_afpd, "main: no servers configured");
        exit(EXITERR_CONF);
    }
    pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);

    /* Register CNID  */
    cnid_init();

    /* watch atp, dsi sockets and ipc parent/child file descriptor. */
    disasociated_ipc_fd = ipc_server_uds(_PATH_AFP_IPC);
    fd_set_listening_sockets();

    /* set limits */
    (void)setlimits();

    afp_child_t *child;
    int fd[2];  /* we only use one, but server_child_add expects [2] */
    pid_t pid;

    /* wait for an appleshare connection. parent remains in the loop
     * while the children get handled by afp_over_{asp,dsi}.  this is
     * currently vulnerable to a denial-of-service attack if a
     * connection is made without an actual login attempt being made
     * afterwards. establishing timeouts for logins is a possible 
     * solution. */
    while (1) {
        LOG(log_maxdebug, logtype_afpd, "main: polling %i fds", fdset_used);
        pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
        ret = poll(fdset, fdset_used, -1);
        pthread_sigmask(SIG_BLOCK, &sigs, NULL);
        int saveerrno = errno;

        if (reloadconfig) {
            nologin++;
            auth_unload();
            fd_reset_listening_sockets();

            LOG(log_info, logtype_afpd, "re-reading configuration file");
            for (config = configs; config; config = config->next)
                if (config->server_cleanup)
                    config->server_cleanup(config);

            /* configfree close atp socket used for DDP tickle, there's an issue
             * with atp tid. */
            configfree(configs, NULL);
            if (!(configs = configinit(&default_options))) {
                LOG(log_error, logtype_afpd, "config re-read: no servers configured");
                exit(EXITERR_CONF);
            }

            fd_set_listening_sockets();

            nologin = 0;
            reloadconfig = 0;
            errno = saveerrno;
            continue;
        }

        if (ret == 0)
            continue;
        
        if (ret < 0) {
            if (errno == EINTR)
                continue;
            LOG(log_error, logtype_afpd, "main: can't wait for input: %s", strerror(errno));
            break;
        }

        for (int i = 0; i < fdset_used; i++) {
            if (fdset[i].revents & (POLLIN | POLLERR | POLLHUP)) {
                switch (polldata[i].fdtype) {

                case LISTEN_FD:
                    config = (AFPConfig *)polldata[i].data;
                    /* config->server_start is afp_config.c:dsi_start() for DSI */
                    if (child = config->server_start(config, configs, server_children)) {
                        /* Add IPC fd to select fd set */
                        fdset_add_fd(&fdset, &polldata, &fdset_used, &fdset_size, child->ipc_fds[0], IPC_FD, child);
                    }
                    break;

                case IPC_FD:
                    child = (afp_child_t *)polldata[i].data;
                    LOG(log_debug, logtype_afpd, "main: IPC request from child[%u]", child->pid);

                    if (ipc_server_read(server_children, child->ipc_fds[0]) != 0) {
                        fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, child->ipc_fds[0]);
                        close(child->ipc_fds[0]);
                        child->ipc_fds[0] = -1;
                        if (child->disasociated) {
                            LOG(log_note, logtype_afpd, "main: removing reattached child[%u]", child->pid);
                            server_child_remove(server_children, CHILD_DSIFORK, child->pid);
                        }
                    }
                    break;

                case DISASOCIATED_IPC_FD:
                    LOG(log_debug, logtype_afpd, "main: IPC reconnect request");
                    if ((fd[0] = accept(disasociated_ipc_fd, NULL, NULL)) == -1) {
                        LOG(log_error, logtype_afpd, "main: accept: %s", strerror(errno));
                        break;
                    }
                    if (readt(fd[0], &pid, sizeof(pid_t), 0, 1) != sizeof(pid_t)) {
                        LOG(log_error, logtype_afpd, "main: readt: %s", strerror(errno));
                        close(fd[0]);
                        break;
                    }
                    LOG(log_note, logtype_afpd, "main: IPC reconnect from pid [%u]", pid);
                    if ((child = server_child_add(server_children, CHILD_DSIFORK, pid, fd)) == NULL) {
                        LOG(log_error, logtype_afpd, "main: server_child_add");
                        close(fd[0]);
                        break;
                    }
                    child->disasociated = 1;
                    fdset_add_fd(&fdset, &polldata, &fdset_used, &fdset_size, fd[0], IPC_FD, child);
                    break;

                default:
                    LOG(log_debug, logtype_afpd, "main: IPC request for unknown type");
                    break;
                } /* switch */
            }  /* if */
        } /* for (i)*/
    } /* while (1) */

    return 0;
}