void sys_exec_checkpoint_script (const char *script_name, const char *archive_name, int checkpoint_number) { pid_t pid; char *argv[4]; char uintbuf[UINTMAX_STRSIZE_BOUND]; pid = xfork (); if (pid != 0) { /* Master */ int status; while (waitpid (pid, &status, 0) == -1) if (errno != EINTR) { waitpid_error (script_name); break; } return; } /* Child */ setenv ("TAR_VERSION", PACKAGE_VERSION, 1); setenv ("TAR_ARCHIVE", archive_name, 1); setenv ("TAR_CHECKPOINT", STRINGIFY_BIGINT (checkpoint_number, uintbuf), 1); setenv ("TAR_BLOCKING_FACTOR", STRINGIFY_BIGINT (blocking_factor, uintbuf), 1); setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1); setenv ("TAR_FORMAT", archive_format_string (current_format == DEFAULT_FORMAT ? archive_format : current_format), 1); argv[0] = "/bin/sh"; argv[1] = "-c"; argv[2] = (char*) script_name; argv[3] = NULL; execv (argv[0], argv); exec_fatal (script_name); }
void seek_warn_details (char const *name, off_t offset) { char buf[UINTMAX_STRSIZE_BOUND]; int e = errno; WARN ((0, e, _("%s: Warning: Cannot seek to %s"), quotearg_colon (name), STRINGIFY_BIGINT (offset, buf))); }
static void dec_to_env (char *envar, uintmax_t num) { char buf[UINTMAX_STRSIZE_BOUND]; char *numstr; numstr = STRINGIFY_BIGINT (num, buf); if (setenv (envar, numstr, 1) != 0) xalloc_die (); }
/* Add a volume label to a part of multi-volume archive */ static void add_volume_label(shfs_arch_t *arch) { char buf[UINTMAX_STRSIZE_BOUND]; char *p = STRINGIFY_BIGINT (volno, buf); char *s = malloc (strlen (volume_label_option) + sizeof VOL_SUFFIX + strlen (p) + 2); sprintf (s, "%s %s %s", volume_label_option, VOL_SUFFIX, p); _write_volume_label(arch, s); free (s); }
/* Catenate file FILE_NAME to the archive without creating a header for it. It had better be a tar file or the archive is screwed. */ static void append_file (char *file_name) { int handle = open (file_name, O_RDONLY | O_BINARY); struct stat stat_data; if (handle < 0) { open_error (file_name); return; } if (fstat (handle, &stat_data) != 0) stat_error (file_name); else { off_t bytes_left = stat_data.st_size; while (bytes_left > 0) { union block *start = find_next_block (); size_t buffer_size = available_space_after (start); size_t status; char buf[UINTMAX_STRSIZE_BOUND]; if (bytes_left < buffer_size) { buffer_size = bytes_left; status = buffer_size % BLOCKSIZE; if (status) memset (start->buffer + bytes_left, 0, BLOCKSIZE - status); } status = safe_read (handle, start->buffer, buffer_size); if (status == SAFE_READ_ERROR) read_fatal_details (file_name, stat_data.st_size - bytes_left, buffer_size); if (status == 0) FATAL_ERROR ((0, 0, ngettext ("%s: File shrank by %s byte", "%s: File shrank by %s bytes", bytes_left), quotearg_colon (file_name), STRINGIFY_BIGINT (bytes_left, buf))); bytes_left -= status; set_next_block_after (start + (status - 1) / BLOCKSIZE); } } if (close (handle) != 0) close_error (file_name); }
void read_fatal_details (char const *name, off_t offset, size_t size) { char buf[UINTMAX_STRSIZE_BOUND]; int e = errno; FATAL_ERROR ((0, e, ngettext ("%s: Read error at byte %s, reading %lu byte", "%s: Read error at byte %s, reading %lu bytes", size), quotearg_colon (name), STRINGIFY_BIGINT (offset, buf), (unsigned long) size)); }
static int format_checkpoint_string (FILE *fp, size_t len, const char *input, bool do_write, unsigned cpn) { const char *opstr = do_write ? gettext ("write") : gettext ("read"); char uintbuf[UINTMAX_STRSIZE_BOUND]; char *cps = STRINGIFY_BIGINT (cpn, uintbuf); const char *ip; static char *argbuf = NULL; static size_t arglen = 0; char *arg = NULL; if (!input) { if (do_write) /* TRANSLATORS: This is a "checkpoint of write operation", *not* "Writing a checkpoint". E.g. in Spanish "Punto de comprobaci@'on de escritura", *not* "Escribiendo un punto de comprobaci@'on" */ input = gettext ("Write checkpoint %u"); else /* TRANSLATORS: This is a "checkpoint of read operation", *not* "Reading a checkpoint". E.g. in Spanish "Punto de comprobaci@'on de lectura", *not* "Leyendo un punto de comprobaci@'on" */ input = gettext ("Read checkpoint %u"); } for (ip = input; *ip; ip++) { if (*ip == '%') { if (*++ip == '{') { arg = getarg (ip, &ip, &argbuf, &arglen); if (!arg) { fputc ('%', fp); fputc (*ip, fp); len += 2; continue; } } switch (*ip) { case 'c': len += format_checkpoint_string (fp, len, def_format, do_write, cpn); break; case 'u': fputs (cps, fp); len += strlen (cps); break; case 's': fputs (opstr, fp); len += strlen (opstr); break; case 'd': len += fprintf (fp, "%.0f", compute_duration ()); break; case 'T': { const char **fmt = checkpoint_total_format, *fmtbuf[3]; struct wordsplit ws; compute_duration (); if (arg) { ws.ws_delim = ","; if (wordsplit (arg, &ws, WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_QUOTE | WRDSF_DELIM)) ERROR ((0, 0, _("cannot split string '%s': %s"), arg, wordsplit_strerror (&ws))); else { int i; for (i = 0; i < ws.ws_wordc; i++) fmtbuf[i] = ws.ws_wordv[i]; for (; i < 3; i++) fmtbuf[i] = NULL; fmt = fmtbuf; } } len += format_total_stats (fp, fmt, ',', 0); if (arg) wordsplit_free (&ws); } break; case 't': { struct timeval tv; struct tm *tm; const char *fmt = arg ? arg : "%c"; gettimeofday (&tv, NULL); tm = localtime (&tv.tv_sec); len += fprintftime (fp, fmt, tm, 0, tv.tv_usec * 1000); } break; case '*': { long w = arg ? strtol (arg, NULL, 10) : getwidth (fp); for (; w > len; len++) fputc (' ', fp); } break; default: fputc ('%', fp); fputc (*ip, fp); len += 2; break; } arg = NULL; } else { fputc (*ip, fp); if (*ip == '\r') { len = 0; tty_cleanup = 1; } else len++; } } fflush (fp); return len; }
int sys_exec_info_script (const char **archive_name, int volume_number) { pid_t pid; char *argv[4]; char uintbuf[UINTMAX_STRSIZE_BOUND]; int p[2]; static RETSIGTYPE (*saved_handler) (int sig); xpipe (p); saved_handler = signal (SIGPIPE, SIG_IGN); pid = xfork (); if (pid != 0) { /* Master */ int rc; int status; char *buf = NULL; size_t size = 0; FILE *fp; xclose (p[PWRITE]); fp = fdopen (p[PREAD], "r"); rc = getline (&buf, &size, fp); fclose (fp); if (rc > 0 && buf[rc-1] == '\n') buf[--rc] = 0; while (waitpid (pid, &status, 0) == -1) if (errno != EINTR) { signal (SIGPIPE, saved_handler); waitpid_error (info_script_option); return -1; } signal (SIGPIPE, saved_handler); if (WIFEXITED (status)) { if (WEXITSTATUS (status) == 0 && rc > 0) *archive_name = buf; else free (buf); return WEXITSTATUS (status); } free (buf); return -1; } /* Child */ setenv ("TAR_VERSION", PACKAGE_VERSION, 1); setenv ("TAR_ARCHIVE", *archive_name, 1); setenv ("TAR_VOLUME", STRINGIFY_BIGINT (volume_number, uintbuf), 1); setenv ("TAR_BLOCKING_FACTOR", STRINGIFY_BIGINT (blocking_factor, uintbuf), 1); setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1); setenv ("TAR_FORMAT", archive_format_string (current_format == DEFAULT_FORMAT ? archive_format : current_format), 1); setenv ("TAR_FD", STRINGIFY_BIGINT (p[PWRITE], uintbuf), 1); xclose (p[PREAD]); argv[0] = "/bin/sh"; argv[1] = "-c"; argv[2] = (char*) info_script_option; argv[3] = NULL; execv (argv[0], argv); exec_fatal (info_script_option); }