예제 #1
0
//!
//! downloads a digest and returns it as a new string (or NULL if error)
//! that the caller must free
//!
//! @param[in] url
//!
//! @return the digested string.
//!
//! @see file2strn()
//!
//! @note the caller must free the returned memory when done.
//!
char *walrus_get_digest(const char *url)
{
    char *digest_str = NULL;
    char *digest_path = strdup("/tmp/walrus-digest-XXXXXX");

    if (!digest_path) {
        logprintfl(EUCAERROR, "out of memory (failed to allocate digest path)\n");
        return digest_path;
    }

    int tmp_fd = safe_mkstemp(digest_path);
    if (tmp_fd < 0) {
        logprintfl(EUCAERROR, "failed to create a digest file %s\n", digest_path);
    } else {
        close(tmp_fd);          // walrus_ routine will reopen the file

        // download a fresh digest
        if (walrus_object_by_url(url, digest_path, 0) != 0) {
            logprintfl(EUCAERROR, "failed to download digest to %s\n", digest_path);
        } else {
            digest_str = file2strn(digest_path, 2000000);
        }
        unlink(digest_path);
    }
    EUCA_FREE(digest_path);
    return digest_str;
}
static int seekable_fd_callback(const char **path_r, void *context)
{
	struct mail_user *user = context;
	string_t *path;
	int fd;

	path = t_str_new(128);
	mail_user_set_get_temp_prefix(path, user->set);
	fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1);
	if (fd == -1) {
		i_error("safe_mkstemp(%s) failed: %m", str_c(path));
		return -1;
	}

	/* we just want the fd, unlink it */
	if (unlink(str_c(path)) < 0) {
		/* shouldn't happen.. */
		i_error("unlink(%s) failed: %m", str_c(path));
		i_close_fd(&fd);
		return -1;
	}

	*path_r = str_c(path);
	return fd;
}
예제 #3
0
int diskutil_write2file (const char * file, const char * str)
{
    int ret = OK;
    char tmpfile [] = "/tmp/euca-temp-XXXXXX";
    int fd = safe_mkstemp (tmpfile);
    if (fd<0) {
        logprintfl (EUCAERROR, "{%u} error: failed to create temporary directory\n", (unsigned int)pthread_self());
        unlink(tmpfile);
        return ERROR;
    }
    int size = strlen (str);
    if (write (fd, str, size) != size) {
        logprintfl (EUCAERROR, "{%u} error: failed to create temporary directory\n", (unsigned int)pthread_self());
        ret = ERROR;
    } else {
        if (diskutil_cp (tmpfile, file) != OK) {
            logprintfl (EUCAERROR, "{%u} error: failed to copy temp file to destination (%s)\n", (unsigned int)pthread_self(), file);
            ret = ERROR;
        }
    }
    close (fd);

    unlink(tmpfile);
    return ret;
}
예제 #4
0
static int program_client_seekable_fd_callback
(const char **path_r, void *context)
{
	struct program_client *pclient = (struct program_client *)context;
	string_t *path;
	int fd;

	path = t_str_new(128);
	str_append(path, pclient->temp_prefix);
	fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1);
	if (fd == -1) {
		i_error("safe_mkstemp(%s) failed: %m", str_c(path));
		return -1;
	}

	/* we just want the fd, unlink it */
	if (unlink(str_c(path)) < 0) {
		/* shouldn't happen.. */
		i_error("unlink(%s) failed: %m", str_c(path));
		i_close_fd(&fd);
		return -1;
	}

	*path_r = str_c(path);
	return fd;
}
예제 #5
0
//!
//!
//!
//! @param[in] file
//! @param[in] str
//!
//! @return EUCA_OK on success or the following error codes:
//!         \li EUCA_ACCESS_ERROR: if we fail to write the given data.
//!         \li EUCA_INVALID_ERROR: if any parameter does not meet the preconditions.
//!         \li EUCA_PERMISSION_ERROR: if we fail to create the temp or destination files.
//!
//! @pre Both file and str parameters must not be NULL.
//!
//! @post On success, the file is created and contains the str data.
//!
int diskutil_write2file(const char *file, const char *str)
{
    int fd = -1;
    int ret = EUCA_OK;
    int size = 0;
    char tmpfile[] = "/tmp/euca-temp-XXXXXX";

    if (file && str) {
        if ((fd = safe_mkstemp(tmpfile)) < 0) {
            LOGERROR("failed to create temporary directory\n");
            unlink(tmpfile);
            return (EUCA_PERMISSION_ERROR);
        }

        size = strlen(str);
        if (write(fd, str, size) != size) {
            LOGERROR("failed to write to temporary directory\n");
            ret = EUCA_ACCESS_ERROR;
        } else {
            if (diskutil_cp(tmpfile, file) != EUCA_OK) {
                LOGERROR("failed to copy temp file (%s)\n", file);
                ret = EUCA_PERMISSION_ERROR;
            }
        }

        close(fd);
        unlink(tmpfile);
        return (ret);
    }

    LOGERROR("failed to write to file. Bad params: file=%p, str=%p\n", file, str);
    return (EUCA_INVALID_ERROR);
}
예제 #6
0
//!
//! Function description.
//!
//! @param[in] file
//!
//! @return
//!
//! @see
//!
//! @pre List of pre-conditions
//!
//! @post List of post conditions
//!
//! @note
//!
int atomic_file_sort_tmpfile(atomic_file * file)
{
    int currlines = 0;
    int i = 0;
    int fd = 0;
    int ret = 0;
    char **contents = NULL;
    char buf[4096] = "";
    char tmpfile[EUCA_MAX_PATH] = "";
    FILE *IFH = NULL;
    FILE *OFH = NULL;

    snprintf(tmpfile, EUCA_MAX_PATH, "%s-XXXXXX", file->dest);
    if ((fd = safe_mkstemp(tmpfile)) < 0) {
        LOGERROR("cannot open tmpfile '%s': check permissions\n", tmpfile);
        return (1);
    }
    if (chmod(tmpfile, 0600)) {
        LOGWARN("chmod failed: was able to create tmpfile '%s', but could not change file permissions\n", tmpfile);
    }
    close(fd);

    buf[0] = '\0';
    if ((IFH = fopen(file->tmpfile, "r")) != NULL) {
        while (fgets(buf, 4096, IFH)) {
            currlines++;
            if ((contents = realloc(contents, sizeof(char *) * currlines)) == NULL) {
                LOGFATAL("out of memory!\n");
                exit(1);
            }
            contents[currlines - 1] = strdup(buf);
        }
        fclose(IFH);

        if (contents) {
            qsort(contents, currlines, sizeof(char *), strcmp_ptr);
            if ((OFH = fopen(tmpfile, "w")) != NULL) {
                for (i = 0; i < currlines; i++) {
                    fprintf(OFH, "%s", contents[i]);
                    EUCA_FREE(contents[i]);
                }
                fclose(OFH);
                if (rename(tmpfile, file->tmpfile)) {
                    LOGERROR("could not rename (move) source file '%s' to dest file '%s': check permissions\n", tmpfile, file->tmpfile);
                    ret = 1;
                }
            }
            EUCA_FREE(contents);
        }
    }

    return (ret);
}
예제 #7
0
//!
//! Initialize the IP Set handler structure
//!
//! @param[in] ipsh pointer to the IP set handler structure
//! @param[in] cmdprefix a string pointer to the prefix to use to run commands
//!
//! @return
//!
//! @see ipt_handler_init()
//!
//! @pre
//!    - The ipsh pointer should not be NULL
//!     - We should be able to create temporary files on the system
//!     - We should be able to execute ebtables commands.
//!
//! @post
//!     - Temporary files on disk: /tmp/ips_file-XXXXXX
//!     - If cmdprefix was provided, the table's cmdprefix field will be set with it
//!
//! @note
//!     - Once temporary file is initialized the filename will be reused throughout the process
//!       lifetime. The file will be truncated/created on each successive calls to the *_handler_init()
//!       method.
//!
int ips_handler_init(ips_handler * ipsh, const char *cmdprefix)
{
    int fd;
    char cmd[EUCA_MAX_PATH];
    char sTempFileName[EUCA_MAX_PATH] = "";

    if (!ipsh) {
        LOGERROR("invalid input\n");
        return (1);
    }

    if (ipsh->init) {
        snprintf(sTempFileName, EUCA_MAX_PATH, ipsh->ips_file);
        if (truncate_file(sTempFileName)) {
            return (1);
        }
        LOGDEBUG("Using already allocated temporary filename: %s\n", sTempFileName);
    } else {
        // Initialize new temp filename, only done once. 
        snprintf(sTempFileName, EUCA_MAX_PATH, "/tmp/ips_file-XXXXXX");
        if ((fd = safe_mkstemp(sTempFileName)) < 0) {
            LOGERROR("cannot create tmpfile '%s': check permissions\n", sTempFileName);
            return (1);
        }
        if (chmod(sTempFileName, 0600)) {
            LOGWARN("chmod failed: was able to create tmpfile '%s', but could not change file permissions\n", sTempFileName);
        }

        LOGDEBUG("Using Newly created temporary filename: %s\n", sTempFileName);
        close(fd);
    }

    bzero(ipsh, sizeof(ips_handler));

    snprintf(ipsh->ips_file, EUCA_MAX_PATH, sTempFileName);

    if (cmdprefix) {
        snprintf(ipsh->cmdprefix, EUCA_MAX_PATH, "%s", cmdprefix);
    } else {
        ipsh->cmdprefix[0] = '\0';
    }
    
    // test required shell-outs
    snprintf(cmd, EUCA_MAX_PATH, "%s ipset -L >/dev/null 2>&1", ipsh->cmdprefix);
    if (system(cmd)) {
        LOGERROR("could not execute required shell out '%s': check command/permissions\n", cmd);
        return (1);
    }

    ipsh->init = 1;
    return (0);
}
예제 #8
0
//!
//! Function description.
//!
//! @param[in] file
//!
//! @return
//!
//! @see
//!
//! @pre List of pre-conditions
//!
//! @post List of post conditions
//!
//! @note
//!
int atomic_file_sort_tmpfile(atomic_file * file)
{
    int cmp = 0;
    int currlines = 0;
    int i = 0;
    int fd = 0;
    int ret = 0;
    char **contents = NULL;
    char buf[4096] = "";
    char tmpfile[MAX_PATH] = "";
    FILE *IFH = NULL;
    FILE *OFH = NULL;

    snprintf(tmpfile, MAX_PATH, "%s-XXXXXX", file->dest);
    if ((fd = safe_mkstemp(tmpfile)) < 0) {
        LOGERROR("cannot open tmpfile '%s'\n", tmpfile);
        return (1);
    }
    chmod(tmpfile, 0644);
    close(fd);

    buf[0] = '\0';
    if ((IFH = fopen(file->tmpfile, "r")) != NULL) {
        while (fgets(buf, 4096, IFH)) {
            currlines++;
            if ((contents = realloc(contents, sizeof(char *) * currlines)) == NULL) {
                LOGFATAL("out of memory!\n");
                exit(1);
            }
            contents[currlines - 1] = strdup(buf);
        }
        fclose(IFH);

        if (contents) {
            qsort(contents, currlines, sizeof(char *), strcmp_ptr);
            if ((OFH = fopen(tmpfile, "w")) != NULL) {
                for (i = 0; i < currlines; i++) {
                    fprintf(OFH, "%s", contents[i]);
                    EUCA_FREE(contents[i]);
                }
                fclose(OFH);
                rename(tmpfile, file->tmpfile);
            }
            EUCA_FREE(contents);
        }
    }

    return (ret);
}
예제 #9
0
//!
//! Write a NULL-terminated string to a file according to a file
//! specification. If 'mktemp' is TRUE, 'path' is expected to be
//! not a file path, but a template for a temporary file name,
//! according to the mkstemp() specification, with six X's in it.
//! Otherwise, 'path' is the path of the file to create and write
//! the string to.
//!
//! @param[in] str String to write to a file.
//! @param[in] path Path of the file to create or mktemp spec.
//! @param[in] flags Same flags as accepted by open() call. Ignored when mktemp is TRUE.
//! @param[in] mode Permissions of the file to create.
//! @param[in] mktemp Flag requesting a temporary file.
//!
//! @return EUCA_OK on success and -1 on failure.
//!
int str2file(const char *str, char *path, int flags, mode_t mode, boolean mktemp)
{
    if (path == NULL)
        return 1;

    int fd;

    // if temporary file was requested, assume that the path is actually
    // a template for mkstemp(), with 6 X's in it, and that it is to be
    // overwritten with the actual file path
    if (mktemp) {
        fd = safe_mkstemp(path);
        if (fd < 0) {
            LOGERROR("cannot create temporary file '%s': %s\n", path, strerror(errno));
            return (-1);
        }
        if (fchmod(fd, mode)) {
            LOGERROR("failed to change permissions on '%s': %s\n", path, strerror(errno));
            close(fd);
            return (-1);
        }
    } else {
        fd = open(path, flags, mode);
        if (fd == -1) {
            LOGERROR("failed to create file '%s': %s\n", path, strerror(errno));
            return (-1);
        }
    }

    if (str) {
        int to_write = strlen(str);
        int offset = 0;
        while (to_write > 0) {
            int wrote = write(fd, str + offset, to_write);
            if (wrote == -1) {
                LOGERROR("failed to write to file '%s': %s\n", path, strerror(errno));
                close(fd);
                return (-1);
            }
            to_write -= wrote;
            offset += wrote;
        }
    }
    close(fd);

    return (EUCA_OK);
}
예제 #10
0
static int
try_create_new(const char *path, const struct file_create_settings *set,
	       int *fd_r, struct file_lock **lock_r,  const char **error_r)
{
	string_t *temp_path = t_str_new(128);
	int fd, orig_errno, ret = -1;
	int mode = set->mode != 0 ? set->mode : 0600;
	uid_t uid = set->uid != 0 ? set->uid : (uid_t)-1;
	uid_t gid = set->gid != 0 ? set->gid : (gid_t)-1;

	str_append(temp_path, path);
	if (uid != (uid_t)-1)
		fd = safe_mkstemp(temp_path, mode, uid, gid);
	else
		fd = safe_mkstemp_group(temp_path, mode, gid, set->gid_origin);
	if (fd == -1) {
		*error_r = t_strdup_printf("safe_mkstemp(%s) failed: %m", path);
		return -1;
	}
	if (file_try_lock_error(fd, str_c(temp_path), F_WRLCK,
				set->lock_method, lock_r, error_r) <= 0) {
	} else if (link(str_c(temp_path), path) < 0) {
		if (errno == EEXIST) {
			/* just created by somebody else */
			ret = 0;
		} else if (errno == ENOENT) {
			/* our temp file was just deleted by somebody else,
			   retry creating it. */
			ret = 0;
		} else {
			*error_r = t_strdup_printf("link(%s, %s) failed: %m",
						   str_c(temp_path), path);
		}
		file_lock_free(lock_r);
	} else {
		i_unlink_if_exists(str_c(temp_path));
		*fd_r = fd;
		return 1;
	}
	orig_errno = errno;
	i_close_fd(&fd);
	i_unlink_if_exists(str_c(temp_path));
	errno = orig_errno;
	return ret;
}
예제 #11
0
static void test_ostream_file_random(void)
{
	struct ostream *output;
	string_t *path = t_str_new(128);
	char buf[MAX_BUFSIZE*4], buf2[MAX_BUFSIZE*4], randbuf[MAX_BUFSIZE];
	unsigned int i, offset, size;
	ssize_t ret;
	int fd;

	memset(buf, 0, sizeof(buf));
	fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1);
	if (fd == -1)
		i_fatal("safe_mkstemp(%s) failed: %m", str_c(path));
	if (unlink(str_c(path)) < 0)
		i_fatal("unlink(%s) failed: %m", str_c(path));
	output = o_stream_create_fd(fd, MAX_BUFSIZE, FALSE);
	o_stream_cork(output);

	size = (rand() % MAX_BUFSIZE) + 1;
	random_fill_weak(randbuf, size);
	memcpy(buf, randbuf, size);
	test_assert(o_stream_send(output, buf, size) > 0);

	for (i = 0; i < 10; i++) {
		offset = rand() % (MAX_BUFSIZE*3);
		size = (rand() % MAX_BUFSIZE) + 1;
		random_fill_weak(randbuf, size);
		memcpy(buf + offset, randbuf, size);
		test_assert(o_stream_pwrite(output, randbuf, size, offset) == 0);
		if (rand() % 10 == 0)
			test_assert(o_stream_flush(output) > 0);
	}

	test_assert(o_stream_flush(output) > 0);
	o_stream_uncork(output);
	ret = pread(fd, buf2, sizeof(buf2), 0);
	if (ret < 0)
		i_fatal("pread() failed: %m");
	else {
		i_assert(ret > 0);
		test_assert(memcmp(buf, buf2, ret) == 0);
	}
	o_stream_unref(&output);
	i_close_fd(&fd);
}
예제 #12
0
파일: textarea.c 프로젝트: Efreak/elinks
static unsigned char *
save_textarea_file(unsigned char *value)
{
	unsigned char *filename;
	FILE *fp = NULL;
	int fd;
	size_t nmemb, len;

	filename = get_tempdir_filename("elinks-area-XXXXXX");
	if (!filename) return NULL;

	fd = safe_mkstemp(filename);
	if (fd < 0) {
		mem_free(filename);
		return NULL;
	}

	len = strlen(value);
	if (len == 0) return filename;

	fp = fdopen(fd, "w");
	if (!fp) {

error:
		unlink(filename);
		mem_free(filename);
		close(fd);
		return NULL;
	}

	nmemb = fwrite(value, len, 1, fp);
	if (nmemb != 1) {
		fclose(fp);
		goto error;
	}

	if (fclose(fp) != 0)
		goto error;

	return filename;
}
예제 #13
0
//!
//! Function description.
//!
//! @param[in] ipsh pointer to the IP set handler structure
//! @param[in] cmdprefix a string pointer to the prefix to use to run commands
//!
//! @return
//!
//! @see
//!
//! @pre
//!
//! @post
//!
//! @note
//!
int ips_handler_init(ips_handler * ipsh, const char *cmdprefix)
{
    int fd;
    char cmd[EUCA_MAX_PATH];

    if (!ipsh) {
        LOGERROR("invalid input\n");
        return (1);
    }
    bzero(ipsh, sizeof(ips_handler));

    snprintf(ipsh->ips_file, EUCA_MAX_PATH, "/tmp/ips_file-XXXXXX");
    fd = safe_mkstemp(ipsh->ips_file);
    if (fd < 0) {
        LOGERROR("cannot create tmpfile '%s': check permissions\n", ipsh->ips_file);
        return (1);
    }
    if (chmod(ipsh->ips_file, 0600)) {
        LOGWARN("chmod failed: was able to create tmpfile '%s', but could not change file permissions\n", ipsh->ips_file);
    }
    close(fd);

    if (cmdprefix) {
        snprintf(ipsh->cmdprefix, EUCA_MAX_PATH, "%s", cmdprefix);
    } else {
        ipsh->cmdprefix[0] = '\0';
    }

    // test required shell-outs
    snprintf(cmd, EUCA_MAX_PATH, "%s ipset -L >/dev/null 2>&1", ipsh->cmdprefix);
    if (system(cmd)) {
        LOGERROR("could not execute required shell out '%s': check command/permissions\n", cmd);
        return (1);
    }

    ipsh->init = 1;
    return (0);
}
예제 #14
0
파일: cache.c 프로젝트: sosilent/euca
char * alloc_tmp_file (const char * name_base, long long size)
{
    if (reserve_work_path(size)) {
        logprintfl (EUCAERROR, "out of work disk space for a temporary file\n");
        return NULL;
    }
    char * path = malloc (EUCA_MAX_PATH);
    if (path==NULL) {
        logprintfl (EUCAERROR, "out of memory in alloc_tmp_file()\n");
        return NULL;
    }

    snprintf (path, EUCA_MAX_PATH, "%s/%s-XXXXXX", get_work_dir(), name_base);
    int tmp_fd = safe_mkstemp (path);
    if (tmp_fd<0) {
        logprintfl (EUCAERROR, "error: failed to create a temporary file under %s\n", path);
        free(path);
        return NULL;
    }
    close (tmp_fd);

    return path;
}
예제 #15
0
int diskutil_grub2_mbr (const char * path, const int part, const char * mnt_pt)
{
    char cmd [1024];
    int rc = 1;

    if (grub_version!=1 && grub_version!=2) {
        logprintfl (EUCAERROR, "{%u} internal error: invocation of diskutil_grub2_mbr without grub found\n", (unsigned int)pthread_self());
        return ERROR;
    } else if (mnt_pt==NULL && grub_version!=1) {
        logprintfl (EUCAERROR, "{%u} internal error: invocation of diskutil_grub2_mbr with grub 1 params\n", (unsigned int)pthread_self());
        return ERROR;
    }
    
    logprintfl (EUCAINFO, "{%u} installing grub in MBR\n", (unsigned int)pthread_self());
    if (grub_version==1) {
        char tmp_file [EUCA_MAX_PATH] = "/tmp/euca-temp-XXXXXX";
        int tfd = safe_mkstemp (tmp_file);
        if (tfd < 0) {
            logprintfl (EUCAINFO, "{%u} error: mkstemp() failed: %s\n", (unsigned int)pthread_self(), strerror (errno));
            return ERROR;
        }

        // create a soft link of the first partition's device mapper entry in the
        // form that grub is looking for (not DISKp1 but just DISK1)
        boolean created_partition_softlink = FALSE;
        char part_path [EUCA_MAX_PATH];
        snprintf (part_path, sizeof (EUCA_MAX_PATH), "%s1", path);
        if (check_path (part_path) != 0) {
            char *output = pruntf (TRUE, "%s /bin/ln -s %sp1 %s", helpers_path[ROOTWRAP], path, part_path);
            if (!output) {
                logprintfl (EUCAINFO, "{%u} warning: failed to create partition device soft-link (%s)\n", (unsigned int)pthread_self(), part_path);
            } else {
                created_partition_softlink = TRUE;
                free (output);
            }
        }

        // we now invoke grub through euca_rootwrap because it may need to operate on
        // devices that are owned by root (e.g. /dev/mapper/euca-dsk-7E4E131B-fca1d769p1)
        snprintf(cmd, sizeof (cmd), "%s %s --batch >%s 2>&1", helpers_path[ROOTWRAP], helpers_path[GRUB], tmp_file);
        logprintfl (EUCADEBUG, "{%u} running %s\n", (unsigned int)pthread_self(), cmd);
        errno = 0;
        FILE * fp = popen (cmd, "w");
        if (fp!=NULL) {
            char s [EUCA_MAX_PATH];
#define _PR fprintf (fp, "%s", s); // logprintfl (EUCADEBUG, "\t%s", s)
            snprintf (s, sizeof (s), "device (hd0) %s\n", path); _PR;
            snprintf (s, sizeof (s), "root (hd0,%d)\n", part);   _PR;
            snprintf (s, sizeof (s), "setup (hd0)\n");           _PR;
            snprintf (s, sizeof (s), "quit\n");                  _PR;
            rc = pclose (fp); // base success on exit code of grub
        }
        if (rc) {
            logprintfl (EUCAERROR, "{%u} error: failed to run grub 1 on disk '%s': %s\n", (unsigned int)pthread_self(), path, strerror (errno));
        } else {
            int read_bytes;
            char buf [1024];
            bzero (buf, sizeof (buf));
            boolean saw_done = FALSE;
            do {
                // read in a line
                int bytes_read = 0;
                while ((sizeof (buf) - 2 - bytes_read)>0 // there is space in buffer for \n and \0
                       && ((read_bytes = read (tfd, buf + bytes_read, 1)) > 0))
                    if (buf [bytes_read++] == '\n')
                        break;
                if (read_bytes < 0) // possibly truncated output, ensure there is newline
                    buf [bytes_read++] = '\n';
                buf [bytes_read] = '\0';
                logprintfl (EUCADEBUG, "\t%s", buf); // log grub 1 prompts and our inputs
                if (strstr (buf, "Done.")) // this indicates that grub 1 succeeded (the message has been there since 2000)
                    saw_done = TRUE;
            } while (read_bytes>0);
            close (tfd);

            if (saw_done==FALSE) {
                logprintfl (EUCAERROR, "{%u} error: failed to run grub 1 on disk '%s'\n", (unsigned int)pthread_self(), path);
                rc = 1;
            } else {
                rc = 0;
            }
        }

        // try to remove the partition device soft link that may have been created above
        if (created_partition_softlink) {
            char * output = pruntf (TRUE, "%s /bin/rm %s", helpers_path[ROOTWRAP], part_path);
            if(!output) {
                logprintfl (EUCAINFO, "{%u} warning: failed to remove partition device soft-link\n", (unsigned int)pthread_self());
            } else {
                free(output);
            }
        }

    } else if (grub_version==2) {
        // create device.map file
        char device_map_path [EUCA_MAX_PATH];
        char device_map_buf  [512];
        snprintf (device_map_path, sizeof (device_map_path), "%s/boot/grub/device.map", mnt_pt);
        snprintf (device_map_buf,  sizeof (device_map_buf),  "(hd0) %s\n", path);
        if (diskutil_write2file (device_map_path, device_map_buf)!=OK) {
            logprintfl (EUCAWARN, "{%u} error: failed to create device.map file\n", (unsigned int)pthread_self());
        } else {
            logprintfl (EUCAINFO, "{%u} wrote to '%s':\n", (unsigned int)pthread_self(), device_map_path);
            logprintfl (EUCAINFO, "{%u} %s", (unsigned int)pthread_self(), device_map_buf);
        }

        char * output = pruntf (TRUE, "%s %s --modules='part_msdos ext2' --root-directory=%s '(hd0)'", helpers_path[ROOTWRAP], helpers_path[GRUB_INSTALL], mnt_pt);
        if (!output) {
            logprintfl (EUCAINFO, "{%u} error: failed to install grub 2 on disk '%s' mounted on '%s'\n", (unsigned int)pthread_self(), path, mnt_pt);
        } else {
            free (output);
            rc = 0;
        }
    }
    
    if (rc==0) 
        return OK;    
    else
        return ERROR;
}
예제 #16
0
int safe_mkstemp_hostpid(string_t *prefix, mode_t mode, uid_t uid, gid_t gid)
{
	str_printfa(prefix, "%s.%s.", my_hostname, my_pid);
	return safe_mkstemp(prefix, mode, uid, gid);
}
예제 #17
0
/**
 * Initialize an IP table handler structure
 *
 * @param pIpt [in] pointer to the IP table handler structure
 * @param psCmdPrefix [in] a constant pointer to a string containing the prefix for EUCA commands
 * @param psPreloadPath [in] a constant pointer to a string containing the path to the IP table preload file
 *
 * @return 0 on success or 1 if any failure occurred
 *
 * @see ipt_handler_free()
 *
 * @pre
 *     - The pIpt pointer should not be NULL
 *     - We should be able to create temporary files on the system
 *     - We should be able to execute the iptables commands
 *
 * @post
 *     On success, the IP table structure will be initialized with the following:
 *     - The ipt_file will point to a temporary file under /tmp/ipt_file-XXXXXX
 *     - If psCmdPrefix was provided, the table's cmdprefix field will be set with it
 *     - If psPreloadPath was provided, the structure's preloadPath will be set with it
 *     -
 *
 * @note
 *     - Once temporary file is initialized the filename will be reused throughout the process
 *       lifetime. The file will be truncated/created on each successive calls to the *_handler_init()
 *       method. 
 */
int ipt_handler_init(ipt_handler *pIpt, const char *psCmdPrefix, const char *psPreloadPath) {
    int fd = 0;
    char sTempFileName[EUCA_MAX_PATH] = "";  // Used to temporarily hold name while we zero out the struct

    // Make sure our pointers are valid
    if (!pIpt) {
        return (1);
    }

    //
    // Initialize the temporary file *ONCE* per process execution
    // This handler init function is called many times, but the temporary file
    // will always be the same for the associated handler struct.
    //
    if (pIpt->init) {
        //
        // Copy filename out of the current ipt_handler struct.
        //
        snprintf(sTempFileName, EUCA_MAX_PATH, pIpt->ipt_file);
        
        //  Truncate the file to ensure we're dealing with a clean slate.
        if (truncate_file(sTempFileName)){
           return (1);
        }
        LOGDEBUG("Using already allocated temporary filename: %s\n", sTempFileName);
        
    } else {
        //
        // Initialize a new temporaty file name
        //
        snprintf(sTempFileName, EUCA_MAX_PATH, "/tmp/ipt_file-XXXXXX");
        if ((fd = safe_mkstemp(sTempFileName)) < 0) {
            LOGERROR("cannot create tmpfile '%s': check permissions\n", sTempFileName);
            return (1);
        }

        // Check to see if we can set the permissions to 0600
        if (chmod(sTempFileName, 0600) < 0) {
            LOGWARN("chmod failed: ipt_file '%s' errno: %d\n", sTempFileName, errno);
        }

        LOGDEBUG("Using newly created temporary filename: %s\n", sTempFileName);
        close(fd);
    }

    // Empty this structure
    bzero(pIpt, sizeof(ipt_handler));

    // Populate the temporary filename
    snprintf(pIpt->ipt_file, EUCA_MAX_PATH, sTempFileName);
    
    // If we have a command prefix (like euca_rootwrap) set it
    pIpt->cmdprefix[0] = '\0';
    if (psCmdPrefix) {
        snprintf(pIpt->cmdprefix, EUCA_MAX_PATH, "%s", psCmdPrefix);
    }
    // If we have a preload file path, set it.
    pIpt->preloadPath[0] = '\0';
    if (psPreloadPath) {
        snprintf(pIpt->preloadPath, EUCA_MAX_PATH, "%s", psPreloadPath);
    }
    // test required shell-outs
    if (euca_execlp_redirect(NULL, NULL, "/dev/null", FALSE, "/dev/null", FALSE, pIpt->cmdprefix, "iptables-save", NULL) != EUCA_OK) {
        LOGERROR("could not execute iptables-save. check command/permissions\n");
        return (1);
    }

    pIpt->init = 1;
    return (0);
}
예제 #18
0
/**
 * Initialize the Ebtables handler structure.
 *
 * @param ebth [in] pointer to the EB table handler structure
 * @param cmdprefix [in] a string pointer to the prefix to use for each system commands
 *
 * @return 0 on success. 1 on failure.
 *
 * @see ipt_handler_init() 
 *
 * @pre
 *     - The ebth pointer should not be NULL
 *     - We should be able to create temporary files on the system
 *     - We should be able to execute ebtables commands.
 *
 * @post
 *     - Temporary files on disk: /tmp/ebt_filter_file-XXXXXX, /tmp/ebt_nat_file-XXXXXX
 *       and /tmp/ebt_asc_file-XXXXXX.
 *     - If cmdprefix was provided, the table's cmdprefix field will be set with it
 *
 * @note
 *     - Once temporary files are initialized the filename will be reused throughout the process
 *       lifetime. The files will be truncated/created on each successive calls to the *_handler_init()
 *       method. 
 */
int ebt_handler_init(ebt_handler *ebth, const char *cmdprefix) {
    int fd;
    char sTempFilterFile[EUCA_MAX_PATH] = "";
    char sTempNatFile[EUCA_MAX_PATH] = "";
    char sTempAscFile[EUCA_MAX_PATH] = "";
    
    if (!ebth) {
        return (1);
    }

    if (ebth->init) {
        snprintf(sTempFilterFile, EUCA_MAX_PATH, ebth->ebt_filter_file);
        snprintf(sTempNatFile, EUCA_MAX_PATH, ebth->ebt_nat_file);
        snprintf(sTempAscFile, EUCA_MAX_PATH, ebth->ebt_asc_file);

        if (truncate_file(sTempFilterFile)) {            
            return (1);
        }

        if (truncate_file(sTempNatFile)) {
            unlink(sTempFilterFile);
            return (1);
        }

        if (truncate_file(sTempAscFile)) {
            unlink(sTempFilterFile);
            unlink(sTempNatFile);
            return (1);
        }
    } else {
        snprintf(sTempFilterFile, EUCA_MAX_PATH, "/tmp/ebt_filter_file-XXXXXX");
        if ((fd = safe_mkstemp(sTempFilterFile))< 0) {
            LOGERROR("cannot create tmpfile '%s': check permissions\n", sTempFilterFile);
            return (1);
        }
        if (chmod(sTempFilterFile, 0600)) {
            LOGWARN("chmod failed: was able to create tmpfile '%s', but could not change file permissions\n", sTempFilterFile);
        }
        close(fd);
        
        snprintf(sTempNatFile, EUCA_MAX_PATH, "/tmp/ebt_nat_file-XXXXXX");
        if ((fd = safe_mkstemp(sTempNatFile)) < 0) {
            LOGERROR("cannot create tmpfile '%s': check permissions\n", sTempNatFile);
            unlink(sTempFilterFile);
            return (1);
        }
        if (chmod(sTempNatFile, 0600)) {
            LOGWARN("chmod failed: was able to create tmpfile '%s', but could not change file permissions\n", sTempNatFile);
        }
        close(fd);
        
        snprintf(sTempAscFile, EUCA_MAX_PATH, "/tmp/ebt_asc_file-XXXXXX");
        if ((fd = safe_mkstemp(sTempAscFile)) < 0) {
            LOGERROR("cannot create tmpfile '%s': check permissions\n", sTempAscFile);
            unlink(sTempFilterFile);
            unlink(sTempNatFile);
            return (1);
        }
        if (chmod(sTempAscFile, 0600)) {
            LOGWARN("chmod failed: was able to create tmpfile '%s', but could not change file permissions\n", sTempAscFile);
        }
        close(fd);
    }
    
    bzero(ebth, sizeof(ebt_handler));

    // Copy names back into handler
    snprintf(ebth->ebt_filter_file, EUCA_MAX_PATH, sTempFilterFile);
    snprintf(ebth->ebt_nat_file, EUCA_MAX_PATH, sTempNatFile);
    snprintf(ebth->ebt_asc_file, EUCA_MAX_PATH, sTempAscFile);

    if (cmdprefix) {
        snprintf(ebth->cmdprefix, EUCA_MAX_PATH, "%s", cmdprefix);
    } else {
        ebth->cmdprefix[0] = '\0';
    }

    // test required shell-outs
    if (euca_execlp_redirect(NULL, NULL, "/dev/null", FALSE, "/dev/null", FALSE, ebth->cmdprefix, "ebtables", "-L", NULL) != EUCA_OK) {
        LOGERROR("could not execute ebtables -L. check command/permissions\n");
        unlink(ebth->ebt_filter_file);
        unlink(ebth->ebt_nat_file);
        unlink(ebth->ebt_asc_file);
        return (1);
    }

    ebth->init = 1;
    return (0);
}
예제 #19
0
//!
//! Function description.
//!
//! @param[in] file
//! @param[in] file_updated
//!
//! @return
//!
//! @see
//!
//! @pre List of pre-conditions
//!
//! @post List of post conditions
//!
//! @note
//!
int atomic_file_get(atomic_file * file, int *file_updated)
{
    int port = 0;
    int fd = 0;
    int ret = 0;
    int rc = 0;
    char *hash = NULL;
    char type[32] = "";
    char hostname[512] = "";
    char path[MAX_PATH] = "";
    char tmpsource[MAX_PATH] = "";
    char tmppath[MAX_PATH] = "";

    if (!file || !file_updated) {
        return (1);
    }

    ret = 0;
    *file_updated = 0;

    snprintf(file->tmpfile, MAX_PATH, "%s", file->tmpfilebase);
    fd = safe_mkstemp(file->tmpfile);
    if (fd < 0) {
        LOGERROR("cannot open tmpfile '%s'\n", file->tmpfile);
        return (1);
    }
    chmod(file->tmpfile, 0644);
    close(fd);

    snprintf(tmpsource, MAX_PATH, "%s", file->source);
    type[0] = tmppath[0] = path[0] = hostname[0] = '\0';
    port = 0;

    tokenize_uri(tmpsource, type, hostname, &port, tmppath);
    snprintf(path, MAX_PATH, "/%s", tmppath);

    if (!strcmp(type, "http")) {
        rc = http_get_timeout(file->source, file->tmpfile, 0, 0, 10, 15);
        if (rc) {
            LOGERROR("http client failed to fetch file URL=%s\n", file->source);
            ret = 1;
        }
    } else if (!strcmp(type, "file")) {
        if (!strlen(path) || copy_file(path, file->tmpfile)) {
            LOGERROR("could not copy source file (%s) to dest file (%s)\n", path, file->tmpfile);
            ret = 1;
        }
    } else {
        LOGWARN("BUG: incompatible URI type (only support http, file): (%s)\n", type);
        ret = 1;
    }

    if (!ret) {
        if (file->tosort) {
            rc = atomic_file_sort_tmpfile(file);
            if (rc) {
                LOGWARN("could not sort tmpfile (%s) inplace\n", file->tmpfile);
            }
        }
        // do checksum - only copy if file has changed
        hash = file2md5str(file->tmpfile);
        if (!hash) {
            LOGERROR("could not compute hash of tmpfile (%s)\n", file->tmpfile);
            ret = 1;
        } else {
            if (file->currhash)
                EUCA_FREE(file->currhash);
            file->currhash = hash;
            if (check_file(file->dest) || strcmp(file->currhash, file->lasthash)) {
                // hashes are different, put new file in place
                LOGINFO("source and destination file contents have changed, triggering update of dest (%s)\n", file->dest);
                LOGDEBUG("renaming file %s -> %s\n", file->tmpfile, file->dest);
                if (rename(file->tmpfile, file->dest)) {
                    LOGERROR("could not rename local copy to dest (%s -> %s)\n", file->tmpfile, file->dest);
                    ret = 1;
                } else {
                    EUCA_FREE(file->lasthash);
                    file->lasthash = strdup(file->currhash);
                    *file_updated = 1;
                }
            }
        }
    }

    unlink(file->tmpfile);
    return (ret);
}
예제 #20
0
 //!
 //! Main entry point of the application
 //!
 //! @param[in] argc the number of parameter passed on the command line
 //! @param[in] argv the list of arguments
 //!
 //! @return EUCA_OK
 //!
int main(int argc, char *argv[])
{
    int ch = 0;
    int result = 0;
    int tmp_fd = -1;
    char *tmp_name = NULL;
    char *command = DEFAULT_COMMAND;
    char *hostport = NULL;
    char *manifest = NULL;
    char *file_name = NULL;
    char *url = NULL;
    char *login = NULL;
    char *password = NULL;
    char request[STRSIZE] = { 0 };
    boolean do_compress = FALSE;
    boolean do_get = FALSE;

    while ((ch = getopt(argc, argv, "dh:m:f:zu:l:p:")) != -1) {
        switch (ch) {
        case 'h':
            hostport = optarg;
            break;
        case 'm':
            manifest = optarg;
            break;
        case 'd':
            debug = TRUE;
            break;
        case 'f':
            file_name = optarg;
            break;
        case 'u':
            url = optarg;
            break;
        case 'l':
            login = optarg;
            break;
        case 'p':
            password = optarg;
            break;
        case 'z':
            do_compress = TRUE;
            break;
        case '?':
        default:
            USAGE();
            break;
        }
    }
    argc -= optind;
    argv += optind;

    if (argc > 0) {
        command = argv[0];
    }

    if (strcmp(command, "GetDecryptedImage") == 0 || strcmp(command, "GetObject") == 0) {
        if (manifest == NULL) {
            fprintf(stderr, "Error: manifest must be specified\n");
            USAGE();
        }
        do_get = TRUE;
    } else if (strcmp(command, "HttpPut") == 0) {
        if (url == NULL || file_name == NULL) {
            fprintf(stderr, "Error: URL and input file must be specified\n");
            USAGE();
        }
        do_get = FALSE;
    } else {
        fprintf(stderr, "Error: unknown command [%s]\n", command);
        USAGE();
    }

    if (do_get) {
        /* use a temporary file for network data */
        tmp_name = strdup("walrus-download-XXXXXX");
        tmp_fd = safe_mkstemp(tmp_name);
        if (tmp_fd < 0) {
            fprintf(stderr, "Error: failed to create a temporary file\n");
            USAGE();
        }
        close(tmp_fd);

        if (hostport) {
            snprintf(request, STRSIZE, "http://%s%s/%s", hostport, WALRUS_ENDPOINT, manifest);
            if (strcmp(command, "GetObject") == 0) {
                result = walrus_object_by_url(request, tmp_name, do_compress);
            } else {
                result = walrus_image_by_manifest_url(request, tmp_name, do_compress);
            }
        } else {
            euca_strncpy(request, manifest, STRSIZE);
            if (strcmp(command, "GetObject") == 0) {
                result = walrus_object_by_path(request, tmp_name, do_compress);
            } else {
                result = walrus_image_by_manifest_path(request, tmp_name, do_compress);
            }
        }

        if (result) {
            /* error has occured */
            cat(tmp_name);
            fprintf(stderr, "\n");  /* in case error doesn't end with a newline */
            remove(tmp_name);
        } else {
            /* all's well */
            if (file_name) {
                rename(tmp_name, file_name);
            } else {
                fprintf(stderr, "Saved output in %s\n", tmp_name);
            }
        }

        EUCA_FREE(tmp_name);
    } else {                    // HttpPut
        result = http_put(file_name, url, login, password);
    }
    return (EUCA_OK);
}
예제 #21
0
//!
//! Function description.
//!
//! @param[in] file
//! @param[in] file_updated
//!
//! @return
//!
//! @see
//!
//! @pre List of pre-conditions
//!
//! @post List of post conditions
//!
//! @note
//!
int atomic_file_get(atomic_file * file, boolean * file_updated)
{
    int port = 0;
    int fd = 0;
    int ret = 0;
    int rc = 0;
    char *hash = NULL;
    char type[32] = "";
    char hostname[512] = "";
    char path[EUCA_MAX_PATH] = "";
    char tmpsource[EUCA_MAX_PATH] = "";
    char tmppath[EUCA_MAX_PATH] = "";

    if (!file || !file_updated) {
        return (1);
    }

    ret = 0;
    *file_updated = FALSE;

    snprintf(file->tmpfile, EUCA_MAX_PATH, "%s", file->tmpfilebase);
    fd = safe_mkstemp(file->tmpfile);
    if (fd < 0) {
        LOGERROR("cannot open tmpfile '%s': check permissions\n", file->tmpfile);
        return (1);
    }
    if (chmod(file->tmpfile, 0600)) {
        LOGWARN("chmod failed: was able to create tmpfile '%s', but could not change file permissions\n", file->tmpfile);
    }
    close(fd);

    snprintf(tmpsource, EUCA_MAX_PATH, "%s", file->source);
    type[0] = tmppath[0] = path[0] = hostname[0] = '\0';
    port = 0;

    tokenize_uri(tmpsource, type, hostname, &port, tmppath);
    snprintf(path, EUCA_MAX_PATH, "/%s", tmppath);

    if (!strcmp(type, "http")) {
        rc = http_get_timeout(file->source, file->tmpfile, 0, 0, 10, 15, NULL);
        if (rc) {
            LOGERROR("http client failed to fetch file URL=%s: check http server status\n", file->source);
            ret = 1;
        }
    } else if (!strcmp(type, "file")) {
        if (!strlen(path) || copy_file(path, file->tmpfile)) {
            LOGERROR("could not copy source file (%s) to dest file (%s): check permissions\n", path, file->tmpfile);
            ret = 1;
        }
    } else {
        LOGWARN("BUG: incompatible URI type (%s) passed to routine (only supports http, file)\n", type);
        ret = 1;
    }

    if (!ret) {
        if (file->dosort) {
            rc = atomic_file_sort_tmpfile(file);
            if (rc) {
                LOGWARN("could not sort tmpfile (%s) inplace: continuing without sort\n", file->tmpfile);
            }
        }
        // do checksum - only copy if file has changed
        hash = file2md5str(file->tmpfile);
        if (!hash) {
            LOGERROR("could not compute hash of tmpfile (%s): check permissions\n", file->tmpfile);
            ret = 1;
        } else {
            if (file->currhash)
                EUCA_FREE(file->currhash);
            file->currhash = hash;
            if (check_file(file->dest) || strcmp(file->currhash, file->lasthash)) {
                // hashes are different, put new file in place
                LOGDEBUG("update triggered due to file update (%s)\n", file->dest);
                LOGDEBUG("source and destination file contents have become different, triggering update of dest (%s)\n", file->dest);
                LOGDEBUG("renaming file %s -> %s\n", file->tmpfile, file->dest);
                if (rename(file->tmpfile, file->dest)) {
                    LOGERROR("could not rename (move) source file '%s' to dest file '%s': check permissions\n", file->tmpfile, file->dest);
                    ret = 1;
                } else {
                    EUCA_FREE(file->lasthash);
                    file->lasthash = strdup(file->currhash);
                    *file_updated = TRUE;
                }
            }
        }
    }

    unlink(file->tmpfile);
    return (ret);
}
예제 #22
0
//!
//! Function description.
//!
//! @param[in] ebth pointer to the EB table handler structure
//! @param[in] cmdprefix a string pointer to the prefix to use for each system commands
//!
//! @return
//!
//! @see
//!
//! @pre
//!
//! @post
//!
//! @note
//!
int ebt_handler_init(ebt_handler * ebth, const char *cmdprefix)
{
    int fd;
    char cmd[EUCA_MAX_PATH];

    if (!ebth) {
        return (1);
    }
    bzero(ebth, sizeof(ebt_handler));

    snprintf(ebth->ebt_filter_file, EUCA_MAX_PATH, "/tmp/ebt_filter_file-XXXXXX");
    fd = safe_mkstemp(ebth->ebt_filter_file);
    if (fd < 0) {
        LOGERROR("cannot create tmpfile '%s': check permissions\n", ebth->ebt_filter_file);
        return (1);
    }
    if (chmod(ebth->ebt_filter_file, 0600)) {
        LOGWARN("chmod failed: was able to create tmpfile '%s', but could not change file permissions\n", ebth->ebt_filter_file);
    }
    close(fd);

    snprintf(ebth->ebt_nat_file, EUCA_MAX_PATH, "/tmp/ebt_nat_file-XXXXXX");
    fd = safe_mkstemp(ebth->ebt_nat_file);
    if (fd < 0) {
        LOGERROR("cannot create tmpfile '%s': check permissions\n", ebth->ebt_nat_file);
        return (1);
    }
    if (chmod(ebth->ebt_nat_file, 0600)) {
        LOGWARN("chmod failed: was able to create tmpfile '%s', but could not change file permissions\n", ebth->ebt_nat_file);
    }
    close(fd);

    snprintf(ebth->ebt_asc_file, EUCA_MAX_PATH, "/tmp/ebt_asc_file-XXXXXX");
    fd = safe_mkstemp(ebth->ebt_asc_file);
    if (fd < 0) {
        LOGERROR("cannot create tmpfile '%s': check permissions\n", ebth->ebt_asc_file);
        unlink(ebth->ebt_filter_file);
        unlink(ebth->ebt_nat_file);
        return (1);
    }
    if (chmod(ebth->ebt_asc_file, 0600)) {
        LOGWARN("chmod failed: was able to create tmpfile '%s', but could not change file permissions\n", ebth->ebt_asc_file);
    }
    close(fd);

    if (cmdprefix) {
        snprintf(ebth->cmdprefix, EUCA_MAX_PATH, "%s", cmdprefix);
    } else {
        ebth->cmdprefix[0] = '\0';
    }

    // test required shell-outs
    snprintf(cmd, EUCA_MAX_PATH, "%s ebtables -L >/dev/null 2>&1", ebth->cmdprefix);
    if (system(cmd)) {
        LOGERROR("could not execute required shell out '%s': check command/permissions\n", cmd);
        unlink(ebth->ebt_filter_file);
        unlink(ebth->ebt_nat_file);
        unlink(ebth->ebt_asc_file);
        return (1);
    }

    ebth->init = 1;
    return (0);
}