/* * Some helpful info... */ static void usage() { fprintf(stderr, "Usage: %s [options] file ...\n", progname); fprintf(stderr, "Displays or adjusts Exif timestamps in the specified " "files.\n"); fprintf(stderr, "Version: %s\n\n", version); fprintf(stderr, "Available options:\n"); fprintf(stderr, " -f\tAnswer 'yes' to any confirmation prompts.\n"); fprintf(stderr, " -i\tConfirm overwrites (default).\n"); fprintf(stderr, " -l\tList files ordered by image created timestamp; " "overrides -t, -v, -w.\n"); fprintf(stderr, " -q\tBe quiet when writing timestamps.\n"); fprintf(stderr, " -s\tSet delimiter to provided string " "(default: \": \").\n"); fprintf(stderr, " -t[acdg]\n\tDisplay/adjust specified timestamp(s), " "if they exist:\n"); fprintf(stderr, "\t a: All available timestamps (default);\n\t " "c: Image created;\n\t g: Image generated; or\n\t d: Image " "digitized.\n"); fprintf(stderr, " -v[+|-]val[ymwdHMS]\n\tAdjust the timestamp(s) by " "the given amount.\n"); fprintf(stderr, " -w\tWrite adjusted timestamp(s).\n"); vary_destroy(v); exit(1); }
int main(int argc, char *argv[]) { struct timezone tz; int ch, rflag; int jflag, nflag; const char *format; char buf[1024]; char *endptr, *fmt; char *tmp; int set_timezone; struct vary *v; const struct vary *badv; struct tm lt; v = NULL; fmt = NULL; (void) setlocale(LC_TIME, ""); tz.tz_dsttime = tz.tz_minuteswest = 0; rflag = 0; jflag = nflag = 0; set_timezone = 0; while ((ch = getopt(argc, argv, "d:f:jnr:t:uv:")) != -1) switch((char)ch) { case 'd': /* daylight savings time */ tz.tz_dsttime = strtol(optarg, &endptr, 10) ? 1 : 0; if (endptr == optarg || *endptr != '\0') usage(); set_timezone = 1; break; case 'f': fmt = optarg; break; case 'j': jflag = 1; /* don't set time */ break; case 'n': /* don't set network */ nflag = 1; break; case 'r': /* user specified seconds */ rflag = 1; tval = strtoq(optarg, &tmp, 0); if (*tmp != 0) usage(); break; case 't': /* minutes west of UTC */ /* error check; don't allow "PST" */ tz.tz_minuteswest = strtol(optarg, &endptr, 10); if (endptr == optarg || *endptr != '\0') usage(); set_timezone = 1; break; case 'u': /* do everything in UTC */ (void)setenv("TZ", "UTC0", 1); break; case 'v': v = vary_append(v, optarg); break; default: usage(); } argc -= optind; argv += optind; /* * If -d or -t, set the timezone or daylight savings time; this * doesn't belong here; the kernel should not know about either. */ if (set_timezone && settimeofday((struct timeval *)NULL, &tz)) err(1, "settimeofday (timezone)"); if (!rflag && time(&tval) == -1) err(1, "time"); format = "%+"; /* allow the operands in any order */ if (*argv && **argv == '+') { format = *argv + 1; ++argv; } if (*argv) { setthetime(fmt, *argv, jflag, nflag); ++argv; } else if (fmt != NULL) usage(); if (*argv && **argv == '+') format = *argv + 1; lt = *localtime(&tval); badv = vary_apply(v, <); if (badv) { fprintf(stderr, "%s: Cannot apply date adjustment\n", badv->arg); vary_destroy(v); usage(); } vary_destroy(v); (void)strftime(buf, sizeof(buf), format, <); (void)printf("%s\n", buf); if (fflush(stdout)) err(1, "stdout"); exit(retval); }
int main(int argc, char **argv) { register int ch; int eval, fnum, wantall; char *rmode, *wmode; FILE *fp; progname = argv[0]; debug = FALSE; ttags = wantall = eval = 0; lflag = qflag = wflag = FALSE; iflag = TRUE; v = NULL; #ifdef WIN32 rmode = "rb"; wmode = "r+b"; #else rmode = "r"; wmode = "r+"; #endif while ((ch = getopt(argc, argv, "filqs:t:v:w")) != -1) switch (ch) { case 'f': iflag = FALSE; break; case 'i': iflag = TRUE; break; case 'l': lflag = TRUE; break; case 'q': qflag = TRUE; break; case 's': delim = optarg; break; case 't': while (*optarg) { switch (*optarg) { case 'c': ttags |= ET_CREATE; break; case 'd': ttags |= ET_DIGI; break; case 'g': ttags |= ET_GEN; break; case 'a': wantall = 1; break; default: usage(); } optarg++; } if (wantall) ttags = 0; break; case 'v': v = vary_append(v, optarg); break; case 'w': wflag = TRUE; break; case '?': default: usage(); } argc -= optind; argv += optind; if (!*argv) usage(); /* Don't be quiet if we're not writing. */ if (qflag && !wflag) qflag = FALSE; /* Prepare an array for sorting. */ if (lflag) { wflag = 0; lorder = (struct linfo *)calloc(argc, sizeof(struct linfo)); if (!lorder) exifdie((const char *)strerror(errno)); } /* Run through the files... */ for (fnum = 0; *argv; ++argv, fnum++) { fname = *argv; /* Only open for read+write if we need to. */ if ((fp = fopen(*argv, wflag ? wmode : rmode)) == NULL) { exifwarn2(strerror(errno), *argv); eval = 1; continue; } /* Print filenames if more than one. */ if (argc > 1 && !lflag && !qflag) printf("%s%s:\n", fnum == 0 ? "" : "\n", *argv); if (lflag) lorder[fnum].fn = fname; if (doit(fp, fnum)) eval = 1; fclose(fp); } /* * We'd like to use mergesort() here (instead of qsort()) because * qsort() isn't stable w/members that compare equal and we exepect * the list of files to frequently already be in order. However, * FreeBSD seems to be the only platform with mergesort(), and I'm * not inclined to include the function... */ if (lflag) { qsort(lorder, argc, sizeof(struct linfo), lcomp); for (fnum = 0; fnum < argc; fnum++) printf("%s\n", lorder[fnum].fn); free(lorder); /* XXX Over in usage()? */ } vary_destroy(v); return (eval); }