Ejemplo n.º 1
0
/*  This opens the rulesfile, but first checks for the lock,
    and if the file is opened sets the lock.

    Returns the pointer to the file, or NULL if failed.
*/
FILE *
rules_file_open(const int debuglvl, const struct vuurmuur_config *cnf, const char *path, const char *mode, int caller)
{
    FILE    *lock_fp = NULL,
            *fp = NULL;
    char    *lock_path = NULL;
    size_t  i = 0,
            lockpath_len = 0;

    /* safety */
    if(!path || !mode)
    {
        (void)vrprint.error(-1, "Internal Error", "parameter problem "
            "(in: %s:%d).", __FUNC__, __LINE__);
        return(NULL);
    }

    lockpath_len = strlen(path) + 6;
    if(lockpath_len == 0)
        return(NULL);

    if(!(lock_path = malloc(lockpath_len)))
    {
        (void)vrprint.error(-1, "Error", "malloc failed: %s "
            "(in: %s:%d).", strerror(errno), __FUNC__, __LINE__);
        return(NULL);
    }

    if(strlcpy(lock_path, path, lockpath_len) >= lockpath_len)
    {
        (void)vrprint.error(-1, "Error", "string overflow "
            "(in: %s:%d).", __FUNC__, __LINE__);
        free(lock_path);
        return(NULL);
    }
    if(strlcat(lock_path, ".LOCK", lockpath_len) >= lockpath_len)
    {
        (void)vrprint.error(-1, "Error", "string overflow "
            "(in: %s:%d).", __FUNC__, __LINE__);
        free(lock_path);
        return(NULL);
    }

    /* try to open the lockfile */
    lock_fp = fopen(lock_path, "r");
    if(lock_fp != NULL)
    {
        /* we are locked! enter wait loop */
        (void)vrprint.warning("Warning", "rulesfile is locked, will try for 60 seconds.");
        for(i = 0; i < 60; i++)
        {
            /* close the lockfile */
            if(fclose(lock_fp) < 0)
                return(NULL);

            lock_fp = fopen(lock_path, "r");
            if(lock_fp != NULL)
            {
                /* we are still locked! */
                sleep(1);
            }
            else
                break;
        }

        /* one last try */
        lock_fp = fopen(lock_path, "r");
        if(lock_fp != NULL)
        {
            (void)vrprint.error(-1, "Error", "opening rulesfile timed out, check if there was a crash.");

            fclose(lock_fp);
            free(lock_path);

            return(NULL);
        }
    }

    lock_fp = fopen(lock_path, "w");
    if(!lock_fp)
    {
        (void)vrprint.error(-1, "Error", "creating lockfile failed: %s.", strerror(errno));
        return(NULL);
    }
    else
    {
        fprintf(lock_fp, "%d\n", caller);

        fclose(lock_fp);
        free(lock_path);
    }

    fp = vuurmuur_fopen(debuglvl, cnf, path, mode);
    return(fp);
}
Ejemplo n.º 2
0
int tell_textdir(void *backend, const char *name, const char *question,
        const char *answer, int overwrite, enum vrmr_objecttypes type)
{
    int retval = 0;
    char *file_location = NULL;
    char line[512] = "", *line_ptr = NULL, *tmp_line_ptr = NULL;
    int i = 0, found = 0, skip = 0;
    FILE *fp = NULL;
    struct vrmr_list storelist;
    struct vrmr_list_node *d_node = NULL;

    assert(backend && name && question && answer);

    vrmr_debug(HIGH,
            "question: %s, answer: %s, name: %s, overwrite: %d, type: %d",
            question, answer, name, overwrite, type);

    struct textdir_backend *tb = (struct textdir_backend *)backend;
    if (!tb->backend_open) {
        vrmr_error(-1, "Error", "backend not opened yet");
        return (-1);
    }

    /* only uppercase allowed */
    while (question[i]) {
        if ((question[i] >= 'a') && (question[i] <= 'z'))
            return (-1);
        ++i;
    }

    if (!(file_location = get_filelocation(backend, name, type)))
        return (-1);

    /*
        first open the file for reading
    */
    if (!(fp = vuurmuur_fopen(tb->cfg, file_location, "r"))) {
        vrmr_error(-1, "Error", "unable to open file '%s' for reading: %s.",
                file_location, strerror(errno));
        free(file_location);
        return (-1);
    }

    /* initialize the store list */
    vrmr_list_setup(&storelist, free);

    /*
        loop trough the current file
    */
    while (fgets(line, MAX_LINE_LENGTH, fp) != NULL) {
        skip = 0;

        size_t line_size = sizeof(line);
        if (!(line_ptr = malloc(line_size))) {
            vrmr_error(-1, "Error", "malloc failed: %s", strerror(errno));
            /* cleanup */
            vrmr_list_cleanup(&storelist);
            free(file_location);
            fclose(fp);
            return (-1);
        }

        if (strncmp(question, line, strlen(question)) == 0 &&
                line[strlen(question)] == '=') {
            if (overwrite && !found) {
                snprintf(line_ptr, line_size, "%s=\"%s\"\n", question, answer);
                found = 1;
            } else if (overwrite && found) {
                skip = 1;
            } else {
                (void)strlcpy(line_ptr, line, line_size);
                found = 1;
            }
        } else {
            (void)strlcpy(line_ptr, line, line_size);
        }

        /*
            now append the line to the storelist, except if we were told to skip
           this one. Then just free the data.
        */
        if (!skip) {
            if (vrmr_list_append(&storelist, line_ptr) == NULL) {
                vrmr_error(-1, "Internal Error",
                        "inserting line into temporary storage list failed");
                /* cleanup */
                vrmr_list_cleanup(&storelist);
                free(line_ptr);
                free(file_location);
                fclose(fp);
                return (-1);
            }
        } else {
            /* free and null */
            free(line_ptr);
            line_ptr = NULL;
        }
    }

    /*
        if we are not overwriting and the type of data is already found
       somewhere, we try to insert is just below the last one.
    */
    if (!overwrite && found) {
        if (!(line_ptr = malloc(sizeof(line)))) {
            vrmr_error(-1, "Error", "malloc failed: %s", strerror(errno));
            /* cleanup */
            vrmr_list_cleanup(&storelist);
            free(file_location);
            fclose(fp);
            return (-1);
        }

        /* assemble the line */
        snprintf(line_ptr, sizeof(line), "%s=\"%s\"\n", question, answer);

        /*
            loop the list bottom up so we match the last one first
        */
        for (d_node = storelist.bot; d_node; d_node = d_node->prev) {
            if (!(tmp_line_ptr = d_node->data)) {
                vrmr_error(-1, "Internal Error", "NULL pointer");
                /* cleanup */
                vrmr_list_cleanup(&storelist);
                free(file_location);
                free(line_ptr);
                fclose(fp);
                return (-1);
            }

            /*
                check if the line is the same. If so insert after it.
            */
            if (strncmp(question, tmp_line_ptr, strlen(question)) == 0) {
                if (vrmr_list_insert_after(&storelist, d_node, line_ptr) ==
                        NULL) {
                    vrmr_error(-1, "Internal Error",
                            "inserting line into temporary storage list "
                            "failed");
                    /* cleanup */
                    vrmr_list_cleanup(&storelist);
                    free(file_location);
                    free(line_ptr);
                    fclose(fp);
                    return (-1);
                }

                /* after inserting we're done */
                line_ptr = NULL;
                break;
            }
            /* Don't free line_ptr yet, because it might be used again in the
             * next iteration */
        }
        /* we no longer need these */
        tmp_line_ptr = NULL;
        free(line_ptr);
        line_ptr = NULL;
    }

    /*
        if its not found, we insert it at the end of the list
    */
    if (found == 0) {
        /* first alloc */
        if (!(line_ptr = malloc(sizeof(line)))) {
            vrmr_error(-1, "Error", "malloc failed: %s.", strerror(errno));

            /* cleanup */
            vrmr_list_cleanup(&storelist);
            free(file_location);
            fclose(fp);
            return (-1);
        }

        snprintf(line_ptr, sizeof(line), "%s=\"%s\"\n", question, answer);

        /* append into the list */
        if (vrmr_list_append(&storelist, line_ptr) == NULL) {
            vrmr_error(-1, "Internal Error",
                    "inserting line into temporary storage list failed");
            /* cleanup */
            vrmr_list_cleanup(&storelist);
            free(file_location);
            free(line_ptr);
            fclose(fp);
            return (-1);
        }

        /* we no longer need this */
        line_ptr = NULL;
    }

    /* close the file */
    (void)fclose(fp);

    /* now open the file for writing */
    if (!(fp = vuurmuur_fopen(tb->cfg, file_location, "w+"))) {
        vrmr_error(-1, "Error", "unable to open file '%s' for writing: %s",
                file_location, strerror(errno));

        /* cleanup */
        vrmr_list_cleanup(&storelist);
        free(file_location);
        return (-1);
    }

    /* print the list into the file */
    for (d_node = storelist.top; d_node; d_node = d_node->next) {
        if (d_node->data == NULL)
            continue;
        fprintf(fp, "%s", (char *)d_node->data);
    }

    (void)fclose(fp);

    /* destroy the temp storage */
    vrmr_list_cleanup(&storelist);
    free(file_location);
    return (retval);
}