From db89554b3108aa64ca7f150e831fb7841382ac9d Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Wed, 10 Jul 2013 20:54:03 -0400 Subject: [PATCH] SetFile Utility --- Tools/SetFile-flags.c | 102 ++++++++++++++++++++++++++ Tools/SetFile-flags.h | 20 ++++++ Tools/SetFile-flags.text | 10 +++ Tools/SetFile.c | 151 +++++++++++++++++++++++++++++++++++++++ Tools/makefile | 11 ++- 5 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 Tools/SetFile-flags.c create mode 100644 Tools/SetFile-flags.h create mode 100644 Tools/SetFile-flags.text create mode 100644 Tools/SetFile.c diff --git a/Tools/SetFile-flags.c b/Tools/SetFile-flags.c new file mode 100644 index 0000000..f689fe7 --- /dev/null +++ b/Tools/SetFile-flags.c @@ -0,0 +1,102 @@ + +#ifdef __ORCAC__ +#pragma optimize 79 +#pragma noroot +#endif + +#include +#include +#include + +#include "SetFile-flags.h" + +void FlagsHelp(void) +{ + fputs("SetFile [options] file...\n", stdout); + fputs("-c creator set the creator\n", stdout); + fputs("-t type set the file type\n", stdout); + fputs("\n", stdout); + exit(0); +} + +struct Flags flags; +int FlagsParse(int argc, char **argv) +{ + char *cp; + char c; + int i; + int j; + + memset(&flags, 0, sizeof(flags)); + + for (i = 1; i < argc; ++i) + { + cp = argv[i]; + c = cp[0]; + + if (c != '-') + return i; + + // -- = end of options. + if (cp[1] == '-' && cp[2] == 0) + return i + 1; + + // now scan all the flags in the string... + for (j = 1; ; ++j) + { + int skip = 0; + + c = cp[j]; + if (c == 0) break; + + switch (c) + { + case 'h': + FlagsHelp(); + break; + case 'c': + // -xarg or -x arg + skip = 1; + if (cp[j + 1]) + { + flags._c = cp + j + 1; + } + else + { + if (++i >= argc) + { + fputs("option requires an argument -- c\n", stderr); + return -1; + } + flags._c = argv[i]; + } + break; + case 't': + // -xarg or -x arg + skip = 1; + if (cp[j + 1]) + { + flags._t = cp + j + 1; + } + else + { + if (++i >= argc) + { + fputs("option requires an argument -- t\n", stderr); + return -1; + } + flags._t = argv[i]; + } + break; + + default: + fprintf(stderr, "illegal option -- %c\n", c); + return -1; + } + + if (skip) break; + } + } + + return i; +} diff --git a/Tools/SetFile-flags.h b/Tools/SetFile-flags.h new file mode 100644 index 0000000..36b28d0 --- /dev/null +++ b/Tools/SetFile-flags.h @@ -0,0 +1,20 @@ + +#ifndef __flags_h__ +#define __flags_h__ + +typedef struct Flags { + char *_c; + char *_t; + + +} Flags; + + +extern struct Flags flags; + +int FlagsParse(int argc, char **argv); + +void FlagsHelp(void); + +#endif + diff --git a/Tools/SetFile-flags.text b/Tools/SetFile-flags.text new file mode 100644 index 0000000..2683d5e --- /dev/null +++ b/Tools/SetFile-flags.text @@ -0,0 +1,10 @@ +--- + +options: + - c: { argument : true } + - t: { argument : true } + +help: + - SetFile [options] file... + - -c creator set the creator + - -t type set the file type diff --git a/Tools/SetFile.c b/Tools/SetFile.c new file mode 100644 index 0000000..e0298ce --- /dev/null +++ b/Tools/SetFile.c @@ -0,0 +1,151 @@ + +#include +#include +#include +#include + +#include +#include + +#include "SetFile-flags.h" + + + +int tox(char c) +{ + c |= 0x20; + if (c >='0' && c <= '9') return c - '0'; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; + return 0; +} + +int hex(const char *in, char *out, int length) +{ + int i; + for (i = 0; i < length; ++i) + { + int tmp = 0; + char c; + + c = *in++; + if (!isxdigit(c)) return -1; + tmp |= tox(c) << 4; + + c = *in++; + if (!isxdigit(c)) return -1; + tmp |= tox(c); + + *out++ = tmp; + } + return 0; +} + +// convert the file/creators... +// format: +// 0x \xdigit{8} +// $ \xdigit{8} +// 4-cc code +int checkcode(const char *in, char *out) +{ + int length; + + length = strlen(in); + + if (length == 4) + { + // 4 cc code. + int i; + for (i = 0; i < 4; ++i) + out[i] = in[i]; + return 0; + } + + if (length == 9 && in[0] == '$') + return hex(in + 1, out, 4); + + if (length ==10 && in[0] == '0' && in[1] == 'x') + return hex(in + 2, out, 4); + + return -1; +} + +int main(int argc, char **argv) +{ + + FInfo newFI; + int optind; + int ok; + int i; + + + optind = FlagsParse(argc, argv); + + argc -= optind; + argv += optind; + + if (argc == 0) + { + FlagsHelp(); + return 0; + } + + + memset(&newFI, 0, sizeof(newFI)); + + if (!flags._t && !flags._c) return 0; + + if (flags._t) + { + ok = checkcode(flags._t, (char *)&newFI.fdType); + if (ok < 0) + { + fprintf(stderr, "SetFile: invalid file type: `%s`\n", flags._t); + exit(1); + } + } + + if (flags._c) + { + ok = checkcode(flags._c, (char *)&newFI.fdCreator); + if (ok < 0) + { + fprintf(stderr, "SetFile: invalid creator type: `%s`\n", flags._c); + exit(1); + } + } + + for (i = 0; i < argc; ++i) + { + FInfo fi; + char buffer[256]; + char *cp; + int l; + + cp = argv[i]; + l = strlen(cp); + if (l > 255) + { + fprintf(stderr, "SetFile: %s: file name too long.\n", cp); + continue; + } + + buffer[0] = l; + memcpy(buffer + 1, cp, l); + + memset(&fi, 0, sizeof(fi)); + + ok = GetFInfo((unsigned char *)buffer, 0, &fi); + + if (flags._t) fi.fdType = newFI.fdType; + if (flags._c) fi.fdCreator = newFI.fdCreator; + + ok = SetFInfo((unsigned char *)buffer, 0, &fi); + if (ok != 0) + { + fprintf(stderr, "SetFile: %s: unable to set finder info: %d\n", cp, ok); + } + } + + exit(0); + return 0; +} \ No newline at end of file diff --git a/Tools/makefile b/Tools/makefile index 8927e42..590ef3f 100644 --- a/Tools/makefile +++ b/Tools/makefile @@ -12,7 +12,7 @@ LIBS = $(Libraries)/Stubs.o \ LDFLAGS = -w -c 'MPS ' -t MPST \ -sn STDIO=Main -sn INTENV=Main -sn %A5Init=Main -all: Help GetEnv Duplicate +all: Help GetEnv Duplicate SetFile GetEnv: GetEnv.c.o mpw Link $(LDFLAGS) -o $@ $^ $(LIBS) @@ -24,6 +24,15 @@ Help: Help.c.o Duplicate: Duplicate.c.o mpw Link $(LDFLAGS) -o $@ $^ $(LIBS) + +SetFile: SetFile.c.o SetFile-flags.c.o + mpw Link $(LDFLAGS) -o $@ $^ $(LIBS) + + +#SetFile.c : SetFile.rl +# ragel -G2 -p -m -o $@ $< + + %.c.o : %.c mpw SC -p $< -o $@