示例#1
0
/**
 * Parse notify command.
 *
 */
static void
set_notify_ns(zone_type* zone, const char* cmd)
{
    const char* str = NULL;
    const char* str2 = NULL;
    char* token = NULL;
    ods_log_assert(cmd);
    ods_log_assert(zone);
    ods_log_assert(zone->name);
    ods_log_assert(zone->adoutbound);
    if (zone->adoutbound->type == ADAPTER_FILE) {
        str = ods_replace(cmd, "%zonefile", zone->adoutbound->configstr);
        if (!str) {
            ods_log_error("[%s] unable to set notify ns: replace zonefile failed",
                engine_str);
        }
        str2 = ods_replace(str, "%zone", zone->name);
        free((void*)str);
    } else {
        str2 = ods_replace(cmd, "%zone", zone->name);
    }
    if (str2) {
        ods_str_trim((char*) str2);
        str = str2;
        if (*str) {
            token = NULL;
            while ((token = strtok((char*) str, " "))) {
                if (*token) {
                    ods_str_list_add(&zone->notify_args, token);
                }
                str = NULL;
            }
        }
        zone->notify_command = (char*) str2;
        zone->notify_ns = zone->notify_args[0];
        ods_log_debug("[%s] set notify ns: %s", engine_str, zone->notify_ns);
    } else {
        ods_log_error("[%s] unable to set notify ns: replace zone failed",
            engine_str);
    }
    return;
}
示例#2
0
/**
 * Interface.
 *
 */
static int
interface_run(FILE* fp, int sockfd, char* cmd)
{
    int maxfdp1 = 0;
    int stdineof = 0;
    int i = 0;
    int n = 0;
    int ret = 0;
    int cmd_written = 0;
    int cmd_response = 0;
    fd_set rset;
    char buf[ODS_SE_MAXLINE];
    int written;

    stdineof = 0;
    FD_ZERO(&rset);
    for(;;) {
        /* prepare */
        if (stdineof == 0) {
            FD_SET(fileno(fp), &rset);
        }
        FD_SET(sockfd, &rset);
        maxfdp1 = max(fileno(fp), sockfd) + 1;

        if (!cmd || cmd_written) {
            /* interactive mode */
            ret = select(maxfdp1, &rset, NULL, NULL, NULL);
            if (ret < 0) {
                if (errno != EINTR && errno != EWOULDBLOCK) {
                    ods_log_warning("[%s] interface select error: %s",
                        cli_str, strerror(errno));
                }
                continue;
            }
        } else if (cmd) {
            /* passive mode */
            ods_writen(sockfd, cmd, strlen(cmd));
            cmd_written = 1;
            stdineof = 1;
            /* Clear the interactive mode / stdin fd from the set */
            FD_CLR(fileno(fp), &rset);
            continue;
        }

        if (cmd && cmd_written && cmd_response) {
            /* normal termination */
            return 0;
        }

        if (FD_ISSET(sockfd, &rset)) {
            /* clear buffer */
            for (i=0; i < ODS_SE_MAXLINE; i++) {
                buf[i] = 0;
            }
            buf[ODS_SE_MAXLINE-1] = '\0';

            /* socket is readable */
            if ((n = read(sockfd, buf, ODS_SE_MAXLINE)) <= 0) {
                if (n < 0) {
                    /* error occurred */
                    fprintf(stderr, "error: %s\n", strerror(errno));
                    return 1;
                } else {
                    /* n==0 */
                    if (stdineof == 1) {
                        /* normal termination */
                        return 0;
                    } else {
                        /* weird termination */
                        fprintf(stderr, "enforcer engine terminated "
                                "prematurely\n");
                        return 1;
                    }
                }
            }

            if (cmd) {
                if (n < SE_CLI_CMDLEN) {
                    /* not enough data received */
                    fprintf(stderr, "not enough response data received "
                            "from daemon.\n");
                    return 1;
                }
                
                /* n >= SE_CLI_CMDLEN : and so it is safe to do buffer 
                    manipulations below. */
                if (strncmp(buf+n-SE_CLI_CMDLEN,"\ncmd> ",SE_CLI_CMDLEN) == 0) {
                
                    /* we have the full response */
                    n -= SE_CLI_CMDLEN;
                    buf[n] = '\0';
                    cmd_response = 1;
                }
            }

            /* n > 0 : when we get to this line... */
            for (written=0; written < n; written += ret) {
                /* write what we got to stdout */
                ret = (int) write(fileno(stdout), &buf[written], n-written);
                /* error and shutdown handling */
                if (ret == 0) {
                    fprintf(stderr, "no write\n");
                    break;
                }
                if (ret < 0) {
                    if (errno == EINTR || errno == EWOULDBLOCK) {
                        ret = 0;
                        continue; /* try again... */
                    }
                    fprintf(stderr, "\n\nwrite error: %s\n", strerror(errno));
                    break;
                }
                /* ret > 0 : when we get here... */
                if (written+ret > n) {
                    fprintf(stderr, "\n\nwrite error: more bytes (%d) written than required (%d)\n", written+ret, n);
                    break;
                }
                /* written+ret < n : means partial write, requires us to loop... */
            }
            if (ods_strcmp(buf, ODS_SE_STOP_RESPONSE) == 0 ) {
                /* we do no further reading, flush */
                write(fileno(stdout), "\n", 1);
                return 0;
            } else if (cmd_response) return 0;
        }

        if (FD_ISSET(fileno(fp), &rset)) {
            /* input is readable */

            if (cmd && cmd_written) {
                /* passive mode */
                stdineof = 1;
                ret = shutdown(sockfd, SHUT_WR);
                if (ret != 0) {
                    fprintf(stderr, "shutdown failed: %s\n",
                        strerror(errno));
                    return 1;
                }
                FD_CLR(fileno(fp), &rset);
                continue;
            }

            /* clear buffer */
            for (i=0; i< ODS_SE_MAXLINE; i++) {
                buf[i] = 0;
            }

            /* interactive mode */
            if ((n = read(fileno(fp), buf, ODS_SE_MAXLINE)) == 0) {
                stdineof = 1;
                ret = shutdown(sockfd, SHUT_WR);
                if (ret != 0) {
                    fprintf(stderr, "shutdown failed: %s\n",
                        strerror(errno));
                    return 1;
                }
                FD_CLR(fileno(fp), &rset);
                continue;
            }
            if (strncmp(buf, "exit", 4) == 0 ||
                strncmp(buf, "quit", 4) == 0) {
                return 0;
            }
            ods_str_trim(buf);
            n = strlen(buf);
            ods_writen(sockfd, buf, n);
        }
    }
}