//! //! 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; }
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; }
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; }
//! //! //! //! @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); }
//! //! 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); }
//! //! 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); }
//! //! 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); }
//! //! 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); }
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; }
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); }
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; }
//! //! 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); }
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; }
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; }
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); }
/** * 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); }
/** * 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); }
//! //! 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); }
//! //! 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); }
//! //! 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); }
//! //! 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); }