📄 genfile.c
字号:
error (EXIT_FAILURE, 0, _("file name contains null character")); obstack_1grow (stk, c); counter++; } obstack_1grow (stk, 0); return (counter == 0 && c == EOF);}voidgenerate_files_from_list (){ FILE *fp = strcmp (files_from, "-") ? fopen (files_from, "rb") : stdin; struct obstack stk; if (!fp) error (EXIT_FAILURE, errno, _("cannot open `%s'"), files_from); obstack_init (&stk); while (!read_name_from_file (fp, &stk)) { char *name = obstack_finish (&stk); generate_simple_file (name); verify_file (name); obstack_free (&stk, name); } fclose (fp); obstack_free (&stk, NULL);}/* Generate Mode: sparse files */static voidmkhole (int fd, off_t displ){ if (lseek (fd, displ, SEEK_CUR) == -1) error (EXIT_FAILURE, errno, "lseek"); ftruncate (fd, lseek (fd, 0, SEEK_CUR));}static voidmksparse (int fd, off_t displ, char *marks){ if (lseek (fd, displ, SEEK_CUR) == -1) error (EXIT_FAILURE, errno, "lseek"); for (; *marks; marks++) { memset (buffer, *marks, block_size); if (write (fd, buffer, block_size) != block_size) error (EXIT_FAILURE, errno, "write"); }}static voidgenerate_sparse_file (int argc, char **argv){ int i; int fd; int flags = O_CREAT | O_RDWR | O_BINARY; if (!file_name) error (EXIT_FAILURE, 0, _("cannot generate sparse files on standard output, use --file option")); if (!seek_offset) flags |= O_TRUNC; fd = open (file_name, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd < 0) error (EXIT_FAILURE, errno, _("cannot open `%s'"), file_name); buffer = xmalloc (block_size); file_length = 0; for (i = 0; i < argc; i += 2) { off_t displ = get_size (argv[i], 1); file_length += displ; if (i == argc-1) { mkhole (fd, displ); break; } else { file_length += block_size * strlen (argv[i+1]); mksparse (fd, displ, argv[i+1]); } } close (fd);}/* Status Mode */voidprint_time (time_t t){ char buf[20]; /* ccyy-mm-dd HH:MM:SS\0 */ strftime (buf, sizeof buf, "%Y-%m-%d %H:%M:%S", gmtime (&t)); printf ("%s ", buf);}voidprint_stat (const char *name){ char *fmt, *p; struct stat st; char buf[UINTMAX_STRSIZE_BOUND]; if (stat (name, &st)) { error (0, errno, _("stat(%s) failed"), name); return; } fmt = strdup (stat_format); for (p = strtok (fmt, ","); p; ) { if (memcmp (p, "st_", 3) == 0) p += 3; if (strcmp (p, "name") == 0) printf ("%s", name); else if (strcmp (p, "dev") == 0) printf ("%lu", (unsigned long) st.st_dev); else if (strcmp (p, "ino") == 0) printf ("%lu", (unsigned long) st.st_ino); else if (strncmp (p, "mode", 4) == 0) { mode_t mask = ~0; if (ispunct (p[4])) { char *q; mask = strtoul (p + 5, &q, 8); if (*q) { printf ("\n"); error (EXIT_FAILURE, 0, _("incorrect mask (near `%s')"), q); } } else if (p[4]) { printf ("\n"); error (EXIT_FAILURE, 0, _("Unknown field `%s'"), p); } printf ("%0o", st.st_mode & mask); } else if (strcmp (p, "nlink") == 0) printf ("%lu", (unsigned long) st.st_nlink); else if (strcmp (p, "uid") == 0) printf ("%ld", (long unsigned) st.st_uid); else if (strcmp (p, "gid") == 0) printf ("%lu", (unsigned long) st.st_gid); else if (strcmp (p, "size") == 0) printf ("%s", umaxtostr (st.st_size, buf)); else if (strcmp (p, "blksize") == 0) printf ("%s", umaxtostr (st.st_blksize, buf)); else if (strcmp (p, "blocks") == 0) printf ("%s", umaxtostr (st.st_blocks, buf)); else if (strcmp (p, "atime") == 0) printf ("%lu", (unsigned long) st.st_atime); else if (strcmp (p, "atimeH") == 0) print_time (st.st_atime); else if (strcmp (p, "mtime") == 0) printf ("%lu", (unsigned long) st.st_mtime); else if (strcmp (p, "mtimeH") == 0) print_time (st.st_mtime); else if (strcmp (p, "ctime") == 0) printf ("%lu", (unsigned long) st.st_ctime); else if (strcmp (p, "ctimeH") == 0) print_time (st.st_ctime); else if (strcmp (p, "sparse") == 0) printf ("%d", ST_IS_SPARSE (st)); else { printf ("\n"); error (EXIT_FAILURE, 0, _("Unknown field `%s'"), p); } p = strtok (NULL, ","); if (p) printf (" "); } printf ("\n"); free (fmt);}/* Exec Mode */voidexec_checkpoint (struct action *p){ if (verbose) printf ("processing checkpoint %lu\n", (unsigned long) p->checkpoint); switch (p->action) { case OPT_TOUCH: { struct timespec ts[2]; ts[0] = ts[1] = p->ts; if (utimens (p->name, ts) != 0) { error (0, errno, _("cannot set time on `%s'"), p->name); break; } } break; case OPT_APPEND: { FILE *fp = fopen (p->name, "ab"); if (!fp) { error (0, errno, _("cannot open `%s'"), p->name); break; } fill (fp, p->size, p->pattern); fclose (fp); } break; case OPT_TRUNCATE: { int fd = open (p->name, O_RDWR | O_BINARY); if (fd == -1) { error (0, errno, _("cannot open `%s'"), p->name); break; } ftruncate (fd, p->size); close (fd); } break; case OPT_EXEC: system (p->name); break; default: abort (); }}voidprocess_checkpoint (size_t n){ struct action *p, *prev = NULL; for (p = action_list; p; ) { struct action *next = p->next; if (p->checkpoint <= n) { exec_checkpoint (p); /* Remove the item from the list */ if (prev) prev->next = next; else action_list = next; free (p); } else prev = p; p = next; }}#define CHECKPOINT_TEXT "Write checkpoint"voidexec_command (void){ int status; pid_t pid; int fd[2]; char *p; FILE *fp; char buf[128]; /* Insert --checkpoint option. FIXME: This assumes that exec_argv does not use traditional tar options (without dash) */ exec_argc++; exec_argv = xrealloc (exec_argv, (exec_argc + 1) * sizeof (*exec_argv)); memmove (exec_argv+2, exec_argv+1, (exec_argc - 1) * sizeof (*exec_argv)); exec_argv[1] = "--checkpoint";#ifdef SIGCHLD /* System V fork+wait does not work if SIGCHLD is ignored. */ signal (SIGCHLD, SIG_DFL);#endif pipe (fd); pid = fork (); if (pid == -1) error (EXIT_FAILURE, errno, "fork"); if (pid == 0) { /* Child */ /* Pipe stderr */ if (fd[1] != 2) dup2 (fd[1], 2); close (fd[0]); /* Make sure POSIX locale is used */ setenv ("LC_ALL", "POSIX", 1); execvp (exec_argv[0], exec_argv); error (EXIT_FAILURE, errno, "execvp"); } /* Master */ close (fd[1]); fp = fdopen (fd[0], "rb"); if (fp == NULL) error (EXIT_FAILURE, errno, "fdopen"); while ((p = fgets (buf, sizeof buf, fp))) { while (*p && !isspace (*p) && *p != ':') p++; if (*p == ':') { for (p++; *p && isspace (*p); p++) ; if (*p && memcmp (p, CHECKPOINT_TEXT, sizeof CHECKPOINT_TEXT - 1) == 0) { char *end; size_t n = strtoul (p + sizeof CHECKPOINT_TEXT - 1, &end, 10); if (!(*end && !isspace (*end))) { process_checkpoint (n); continue; } } } fprintf (stderr, "%s", buf); } /* Collect exit status */ waitpid (pid, &status, 0); if (verbose) { if (WIFEXITED (status)) { if (WEXITSTATUS (status) == 0) printf (_("Command exited successfully\n")); else printf (_("Command failed with status %d\n"), WEXITSTATUS (status)); } else if (WIFSIGNALED (status)) printf (_("Command terminated on signal %d\n"), WTERMSIG (status)); else if (WIFSTOPPED (status)) printf (_("Command stopped on signal %d\n"), WSTOPSIG (status));#ifdef WCOREDUMP else if (WCOREDUMP (status)) printf (_("Command dumped core\n"));#endif else printf(_("Command terminated\n")); } if (WIFEXITED (status)) exit (WEXITSTATUS (status)); exit (EXIT_FAILURE);}intmain (int argc, char **argv){ int index; program_name = argv[0]; setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); get_date (&touch_time, "now", NULL); /* Decode command options. */ if (argp_parse (&argp, argc, argv, 0, &index, NULL)) exit (EXIT_FAILURE); argc -= index; argv += index; switch (mode) { case mode_stat: if (argc == 0) error (EXIT_FAILURE, 0, _("--stat requires file names")); while (argc--) print_stat (*argv++); break; case mode_sparse: generate_sparse_file (argc, argv); verify_file (file_name); break; case mode_generate: if (argc) error (EXIT_FAILURE, 0, _("too many arguments")); if (files_from) generate_files_from_list (); else { generate_simple_file (file_name); verify_file (file_name); } break; case mode_exec: exec_command (); break; default: /* Just in case */ abort (); } exit (EXIT_SUCCESS);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -