gint copy_file(const gchar *s, const gchar *t) { FILE *fi = NULL; FILE *fo = NULL; gchar *sl, *tl; gchar buf[4096]; gint b; sl = path_from_utf8(s); tl = path_from_utf8(t); if (hard_linked(sl, tl)) { g_free(sl); g_free(tl); return TRUE; } fi = fopen(sl, "rb"); if (fi) { fo = fopen(tl, "wb"); if (!fo) { fclose(fi); fi = NULL; } } g_free(sl); g_free(tl); if (!fi || !fo) return FALSE; while((b = fread(buf, sizeof(char), 4096, fi)) && b != 0) { if (fwrite(buf, sizeof(char), b, fo) != b) { fclose(fi); fclose(fo); return FALSE; } } fclose(fi); fclose(fo); copy_file_attributes(s, t, TRUE, TRUE); return TRUE; }
int main(int argc, char **argv) { int opt; int opt_uncompress = FALSE; int opt_stdout = FALSE; int block_size = 0; size_t rsize = 0; size_t wsize = 0; const char *format_name = NULL; stream_format_t *fmt = &snzip_format; char *progname = strrchr(argv[0], PATH_DELIMITER); if (progname != NULL) { progname++; } else { progname = argv[0]; } trace("progname = %s\n", progname); if (strstr(progname, "un") != NULL) { trace("\"un\" is found in %s\n", progname); opt_uncompress = TRUE; } if (strstr(progname, "cat") != NULL) { trace("\"cat\" is found in %s\n", progname); opt_stdout = TRUE; opt_uncompress = TRUE; } while ((opt = getopt(argc, argv, "cdt:hb:B:R:W:T")) != -1) { switch (opt) { case 'c': opt_stdout = TRUE; break; case 'd': opt_uncompress = TRUE; break; case 't': format_name = optarg; break; case 'h': show_usage(progname, 0); break; case 'b': block_size = atoi(optarg); break; case 'B': block_size = 1ul << atoi(optarg); break; case 'R': rsize = strtoul(optarg, NULL, 10); break; case 'W': wsize = strtoul(optarg, NULL, 10); break; case 'T': trace_flag = TRUE; break; case '?': show_usage(progname, 1); break; } } #ifdef WIN32 _setmode(0, _O_BINARY); _setmode(1, _O_BINARY); #endif if (format_name != NULL) { fmt = find_stream_format_by_name(format_name); if (fmt == NULL) { fprintf(stderr, "Unknown file format name %s\n", format_name); return 1; } } if (optind == argc) { trace("no arguments are set.\n"); if (isatty(1)) { /* stdout is a terminal */ fprintf(stderr, "I won't write compressed data to a terminal.\n"); fprintf(stderr, "For help, type: '%s -h'.\n", progname); return 1; } if (opt_uncompress) { if (format_name == NULL) { fmt = find_stream_format_by_first_byte(stdin); if (fmt == NULL) { return 1; } } return fmt->uncompress(stdin, stdout); } else { return fmt->compress(stdin, stdout, block_size); } } while (optind < argc) { char *infile = argv[optind++]; size_t infilelen = strlen(infile); char outfile[PATH_MAX]; FILE *infp; FILE *outfp; /* check input file and open it. */ const char *suffix = strrchr(infile, '.'); if (suffix != NULL) { stream_format_t *fmt_tmp = find_stream_format_by_suffix(suffix + 1); if (fmt_tmp == NULL && opt_uncompress) { print_error("%s has unknown suffix.\n", infile); continue; } if (fmt_tmp != NULL && !opt_uncompress) { print_error("%s already has %s suffix\n", infile, fmt_tmp->suffix); continue; } } infp = fopen(infile, "rb" OPTIMIZE_SEQUENTIAL); if (infp == NULL) { print_error("Failed to open %s for read\n", infile); exit(1); } if (rsize != 0) { trace("setvbuf(infp, NULL, _IOFBF, %ld)\n", (long)rsize); setvbuf(infp, NULL, _IOFBF, rsize); } #ifdef HAVE_POSIX_FADVISE posix_fadvise(fileno(infp), 0, 0, POSIX_FADV_SEQUENTIAL); #endif /* determine the file format */ if (opt_uncompress) { fmt = find_stream_format_by_first_byte(infp); if (fmt == NULL) { exit(1); } } /* check output file and open it. */ if (opt_stdout) { strcpy(outfile, "-"); outfp = stdout; } else { size_t suffixlen = strlen(fmt->suffix); if (opt_uncompress) { if (infilelen - suffixlen >= sizeof(outfile)) { print_error("%s has too long file name.\n", infile); exit(1); } memcpy(outfile, infile, infilelen - suffixlen - 1); outfile[infilelen - suffixlen - 1] = '\0'; } else { if (infilelen + suffixlen + 2 >= sizeof(outfile)) { print_error("%s has too long file name.\n", infile); exit(1); } sprintf(outfile, "%s.%s", infile, fmt->suffix); } outfp = fopen(outfile, "wb" OPTIMIZE_SEQUENTIAL); if (outfp == NULL) { print_error("Failed to open %s for write\n", outfile); exit(1); } } if (wsize != 0) { trace("setvbuf(outfp, NULL, _IOFBF, %ld)\n", (long)wsize); setvbuf(outfp, NULL, _IOFBF, wsize); } if (opt_uncompress) { trace("uncompress %s\n", infile); if (fmt->uncompress(infp, outfp) != 0) { if (outfp != stdout) { unlink(outfile); } return 1; } } else { trace("compress %s\n", infile); if (fmt->compress(infp, outfp, block_size) != 0) { if (outfp != stdout) { unlink(outfile); } return 1; } } if (!opt_stdout) { fflush(outfp); copy_file_attributes(fileno(infp), fileno(outfp), outfile); } fclose(infp); if (outfp != stdout) { fclose(outfp); } if (!opt_stdout) { int rv = unlink(infile); trace("unlink(\"%s\") => %d (errno = %d)\n", infile, rv, rv ? errno : 0); } } return 0; }
static gint collection_save_private(CollectionData *cd, const gchar *path) { FILE *f; GList *work; gchar *tmp_path; gchar *pathl; mode_t save_mask; if (!path && !cd->path) return FALSE; if (!path) { path = cd->path; } tmp_path = unique_filename(path, ".tmp", "_", 3); if (!tmp_path) return FALSE; pathl = path_from_utf8(tmp_path); save_mask = umask(0077); f = fopen(pathl, "w"); umask(save_mask); g_free(pathl); if (!f) { /* file open failed */ printf("failed to open collection (write) \"%s\"\n", tmp_path); g_free(tmp_path); return FALSE; } fprintf(f, "%s collection\n", GQVIEW_COLLECTION_MARKER); fprintf(f, "#created with GQview version %s\n", VERSION); collection_update_geometry(cd); if (cd->window_read) { fprintf(f, "#geometry: %d %d %d %d\n", cd->window_x, cd->window_y, cd->window_w, cd->window_h); } work = cd->list; while (work) { CollectInfo *ci = work->data; if (fprintf(f, "\"%s\"\n", ci->path) < 0) { fclose(f); printf("Error writing to %s\n", tmp_path); unlink_file(tmp_path); g_free(tmp_path); return FALSE; } work = work->next; } fprintf(f, "#end\n"); fclose(f); copy_file_attributes(path, tmp_path, TRUE, FALSE); if (!rename_file(tmp_path, path)) { printf("collection save unable to rename %s to %s\n", tmp_path, path); unlink_file(tmp_path); g_free(tmp_path); return FALSE; } g_free(tmp_path); if (!cd->path || strcmp(path, cd->path) != 0) { gchar *buf = cd->path; cd->path = g_strdup(path); path = cd->path; g_free(buf); g_free(cd->name); cd->name = g_strdup(filename_from_path(cd->path)); collection_path_changed(cd); } cd->changed = FALSE; return TRUE; }