diff --git a/Delete-flags.c b/Delete-flags.c new file mode 100644 index 0000000..0d435de --- /dev/null +++ b/Delete-flags.c @@ -0,0 +1,101 @@ + +#ifdef __ORCAC__ +#pragma optimize 79 +#pragma noroot +#endif + +#include +#include +#include + +#include "Delete-flags.h" + +void FlagsHelp(void) +{ + fputs("Delete [options] name...\n", stdout); + fputs("-y delete directory contents (avoids dialog)\n", stdout); + fputs("-n don't delete directory contents (avoids dialog)\n", stdout); + fputs("-c cancel if a directory is to be deleted (avoids dialog)\n", stdout); + fputs("-i ignore errors (no diagnostics)\n", stdout); + fputs("-p write progress information to diagnostics\n", stdout); + fputs("\n", stdout); + exit(0); +} + +struct Flags flags; +int FlagsParse(int argc, char **argv) +{ + char *cp; + char *optarg; + + char c; + int i; + int j; + int eof; // end-of-flags + int mindex; // mutation index. + + memset(&flags, 0, sizeof(flags)); + + for (i = 1, mindex = 1, eof = 0; i < argc; ++i) + { + cp = argv[i]; + c = cp[0]; + + if (c != '-' || eof) + { + if (i != mindex) argv[mindex] = argv[i]; + mindex++; + continue; + } + + // -- = end of options. + if (cp[1] == '-' && cp[2] == 0) + { + eof = 1; + continue; + } + + // now scan all the flags in the string... + optarg = NULL; + for (j = 1; ; ++j) + { + c = cp[j]; + if (c == 0) break; + + switch (c) + { + case 'h': + FlagsHelp(); + break; + case 'y': + case 'Y': + flags._y = 1; + break; + case 'n': + case 'N': + flags._n = 1; + break; + case 'c': + case 'C': + flags._c = 1; + break; + case 'i': + case 'I': + flags._i = 1; + break; + case 'p': + case 'P': + flags._p = 1; + break; + + default: + fprintf(stderr, "illegal option -- %c\n", c); + exit(1); + } + + if (optarg) break; + } + } + + return mindex; +} diff --git a/Delete-flags.h b/Delete-flags.h new file mode 100644 index 0000000..e433f0e --- /dev/null +++ b/Delete-flags.h @@ -0,0 +1,23 @@ + +#ifndef __flags_h__ +#define __flags_h__ + +typedef struct Flags { + + unsigned _y:1; + unsigned _n:1; + unsigned _c:1; + unsigned _i:1; + unsigned _p:1; + +} Flags; + + +extern struct Flags flags; + +int FlagsParse(int argc, char **argv); + +void FlagsHelp(void); + +#endif + diff --git a/Delete.c b/Delete.c new file mode 100644 index 0000000..db70957 --- /dev/null +++ b/Delete.c @@ -0,0 +1,118 @@ +/* + * Delete # delete files and directories + * Delete [-y | -n | -c] [-i] [-p] name... + * -y # delete directory contents (avoids dialog) + * -n # don't delete directory contents (avoids dialog) + * -c # cancel if a directory is to be deleted (avoids dialog) + * -i # ignore errors (no diagnostics) + * -p # write progress information to diagnostics + */ + +/* + * return value: + * 0 - all ok + * 1 - syntax error + * 2 - delete error + * 4 - canceled. + */ + + +#include +#include +#include +#include +#include + +#include "Delete-flags.h" + +char *c2p(const char *cp) +{ + int length; + char *p; + + if (!cp) return NULL; + length = strlen(cp); + if (length > 255) + { + fprintf(stderr, "Error: Pathname is too long.\n"); + exit(1); + return NULL; + } + + p = malloc(length + 2); // + 2 for \0 and length. + if (!p) + { + fprintf(stderr, "Error: unable to allocate memory.\n"); + exit(1); + return NULL; + } + + p[0] = length; + memcpy(p + 1, cp, length + 1); + return p; +} + +// -1 - error. +// 0 - no file +// 1 - regular file +// 2 - directory. +int mode(const char *path) +{ + char *pname; + CInfoPBRec rec; + OSErr status; + + memset(&rec, 0, sizeof(rec)); + + pname = c2p(path); + if (!pname) return -1; + + rec.hFileInfo.ioNamePtr = (unsigned char *)pname; + status = PBGetCatInfo(&rec, false); + free(pname); + + if (status) return 0; + if (rec.hFileInfo.ioFlAttrib & kioFlAttribDirMask) + return 2; + + return 1; +} + +static char error_message[255]; + +int main(int argc, char **argv) { + int i; + int status = 0; + + argc = FlagsParse(argc, argv); + + if (argc == 1) + { + FlagsHelp(); + return 1; + } + + pascalStrings = false; + InitErrMgr(NULL, NULL, true); + + for (i = 1 ; i < argc; ++i) { + OSErr err; + char *file = argv[i]; + char *p = c2p(file); + // todo -- y/n/c flags. + + err = FSDelete((unsigned char *)p, 0); + if (err && !flags._i) { + fprintf(stderr, "### Delete - unable to delete %s\n", file); + fprintf(stderr, "# %s\n", GetSysErrText(err, error_message)); + status = 2; + break; + } + if (!err && flags._p) { + fprintf(stderr, "%s deleted.\n", file); + } + free(p); + } + CloseErrMgr(); + return status; +} diff --git a/makefile b/makefile index 1d82c13..50ca61c 100644 --- a/makefile +++ b/makefile @@ -49,6 +49,10 @@ Duplicate: Duplicate.c.o $(MPW) Link $(LDFLAGS) -o $@ $^ $(LIBS) +Delete: Delete.c.o Delete-flags.c.o + $(MPW) Link $(LDFLAGS) -o $@ $^ $(LIBS) + + SetFile: SetFile.c.o SetFile-flags.c.o $(MPW) Link $(LDFLAGS) -o $@ $^ $(LIBS)