split mow-tools into separate repo

This commit is contained in:
Kelvin Sherlock 2013-07-14 18:48:08 -04:00
parent 92ef78516c
commit 3f55b2b8ab
9 changed files with 0 additions and 763 deletions

View File

@ -1,346 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <Files.h>
/*
Duplicate # duplicate files and directories
Duplicate [-y | -n | -c] [-p] [-d | -r] name... target > progress
-y # overwrite target files (avoids dialog)
-n # don't overwrite target files (avoids dialog)
-c # cancel if conflict occurs (avoids dialog)
-p # write progress information to diagnostics
-d # duplicate data fork only
-r # duplicate resource fork only
-rs # resolve leaf aliases in the source path(s)
-rt # resolve leaf aliases in the target path
-f # preserve Finder icon locations
*/
// todo -- support src1 src2 ... dest/
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;
}
void help(void)
{
fprintf(stdout, "Usage: Duplicate [-y | -n | -c] [-p] [-d |-r] source destination\n");
}
int getopt(int *opts, int argc, char **argv)
{
int i = 0;
for (i = 1; i < argc; ++i)
{
char *str = argv[i];
char c = str[0];
if (c != '-') return i;
++str;
// -- to terminate
if (str[0] == '-' && str[1] == 0)
return i + 1;
// skip -rt, -rs
if (str[0] == 'r' && str[1] == 's' && str[2] == 0)
continue;
if (str[0] == 'r' && str[1] == 't' && str[2] == 0)
continue;
for (; *str; ++str)
{
c = *str;
switch(c)
{
case 'r':
case 'd':
opts['r' - 'a'] = 0;
opts['d' - 'a'] = 0;
opts[c - 'a'] = 1;
break;
case 'y':
case 'n':
case 'c':
opts['y' - 'a'] = 0;
opts['n' - 'a'] = 0;
opts['c' - 'a'] = 0;
opts[c - 'a'] = 1;
break;
case 'p':
opts[c - 'a'] = 1;
break;
case 'h':
help();
exit(0);
break;
default:
fprintf(stderr, "Duplicate - Invalid flag: \"%c\"\n", c);
exit(1);
break;
}
}
}
return i;
}
int copyFork(const char *src, const char *dest, unsigned fork)
{
static char buffer[4096];
int rfd, wfd;
int rv;
fork = fork ? O_RSRC : 0;
rfd = open(src, O_RDONLY | O_BINARY | fork);
if (rfd < 0)
{
fprintf(stderr, "Error opening %s: %s\n", src, strerror(errno));
return -1;
}
// no 3rd parameter to open.
wfd = open(dest, O_WRONLY | O_BINARY | O_CREAT |O_TRUNC| fork);
if (wfd < 0)
{
fprintf(stderr, "Error opening %s: %s\n", dest, strerror(errno));
close(rfd);
return -1;
}
rv = -1;
for (;;)
{
ssize_t rsize;
ssize_t wsize;
rsize = read(rfd, buffer, sizeof(buffer));
if (rsize == 0)
{
rv = 0;
break;
}
if (rsize < 0)
{
if (errno == EINTR) continue;
fprintf(stderr, "Error reading %s: %s\n", src, strerror(errno));
break;
}
wsize = write(wfd, buffer, rsize);
if (wsize != rsize)
{
fprintf(stderr, "Error writing %s: %s\n", dest, strerror(errno));
break;
}
}
close(rfd);
close(wfd);
return rv;
}
int copyFinderInfo(const char *src, const char *dest)
{
FInfo finderInfo;
OSErr status;
char *psrc;
char *pdest;
psrc = c2p(src);
pdest = c2p(dest);
if (!psrc || !pdest) return -1;
// getfinfo/setfinfo seem to have bugs.
memset(&finderInfo, 0, sizeof(finderInfo));
status = GetFInfo((unsigned char *)psrc, 0, &finderInfo);
if (status == 0)
{
status = SetFInfo((unsigned char *)pdest, 0, &finderInfo);
}
free(psrc);
free(pdest);
if (status) return -1;
return 0;
}
int createFile(const char *src, const char *dest)
{
FInfo finderInfo;
OSErr status;
char *psrc;
char *pdest;
psrc = c2p(src);
pdest = c2p(dest);
if (!psrc || !pdest) return -1;
memset(&finderInfo, 0, sizeof(finderInfo));
status = GetFInfo((unsigned char *)psrc, 0, &finderInfo);
status = Create((unsigned char *)pdest, 0, finderInfo.fdCreator, finderInfo.fdType);
free(psrc);
free(pdest);
if (status) return -1;
return 0;
}
// -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;
}
int main(int argc, char **argv)
{
int opts[26];
int optind;
int ok;
char *src;
char *dest;
int m;
memset(opts, 0, sizeof(opts));
opts['n' - 'a'] = 1;
optind = getopt(opts, argc, argv);
argc -= optind;
argv += optind;
if (argc != 2)
{
help();
exit(1);
}
src = argv[0];
dest = argv[1];
// 1. check if src exists
// 2. check if dest exists
// 3. copy data fork unless -r
// 4. copy resource fork unless -d
// 5. copy finder info.
ok = 0;
// -n - do not overwrite
// -c - cancel if conflict
m = mode(dest);
if (m == 2)
{
fprintf(stderr, "Error: directory destination is not yet supported.\n");
exit(1);
}
if (m == 0 && opts['r' - 'a'])
{
// workaround to create the file if
// only copying the resource fork.
// TODO -- call Create(name, 0, creator, filetype)
if (opts['p' - 'a'])
printf("Creating file %s\n", dest);
ok = createFile(src, dest);
if (ok < 0)
{
fprintf(stderr, "Error creating %s\n", dest);
exit(1);
}
}
if (m == 1)
{
// todo -- should this check at the file level or at the fork level?
// seems to check at the file level.
// file exists.
if (opts['c' - 'a'] || opts['n' - 'a'])
{
if (opts['p' - 'a'])
{
printf("File exists - nothing done.\n");
}
exit(0);
}
}
if (opts['r' - 'a'] == 0)
{
if (opts['p' - 'a'])
printf("Copying Data Fork.\n");
ok = copyFork(src, dest, 0);
}
if (opts['d' - 'a'] == 0)
{
if (opts['p' - 'a'])
printf("Copying Resource Fork.\n");
ok = copyFork(src, dest, 1);
}
return ok;
}

View File

@ -1,28 +0,0 @@
/*
*
* GetEnv variable
* read an mpw variable.
* eg: CLibraries=`mpw GetEnv CLibraries`
* (makefile) CLibraries = $(shell mpw GetEnv CLibraries)
* flags to do name = value?
*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char *value;
char *name;
if (argc != 2)
{
return 1;
}
name = argv[1];
value = getenv(name);
// value == null if not defined.
if (value) puts(value);
return 0;
}

View File

@ -1 +0,0 @@
/* * MPW Help utility. * * help topic * does a cat of $ShellDirectory:Help:topic */ /* * MPW 3.2 * * C Help.c -o Help.c.o -r {SymOptions} * * Link {SymOptions} -w -c 'MPS ' -t MPST Help.c.o ∂ * -sn STDIO=Main ∂ * -sn INTENV=Main ∂ * -sn %A5Init=Main ∂ * "{Libraries}"Stubs.o ∂ * "{CLibraries}"StdCLib.o ∂ * "{Libraries}"Interface.o ∂ * "{Libraries}"Runtime.o ∂ * "{Libraries}"ToolLibs.o ∂ * -o Help * */ #include <stdio.h> #include <stdlib.h> #include <string.h> char *base(char *str) { char *rv = str; char *tmp = str; if (!str) return str; for (tmp = str; *tmp; ++tmp) { char c = *tmp; if (c == ':' || c == '/') rv = tmp + 1; } return rv; } void help(char *root, char *topic) { int l; char *path; FILE *fp; // todo -- check if they're being stupid or malicious and // handle / or : chars. topic = base(topic); if (!topic || !*topic) { return; } l = strlen(root) + strlen("Help:") + strlen(topic) + 1; path = malloc(1); if (!path) { fprintf(stderr, "### Help - Memory allocation failure.\n"); return; } sprintf(path, "%sHelp:%s", root, topic); fp = fopen(path, "r"); free(path); if (!fp) { fprintf(stderr, "### Help - \"%s\" was not found.\n", topic); return; } for(;;) { char buffer[512]; int count; count = fread(buffer, 1, sizeof(buffer), fp); if (count == 0) break; fwrite(buffer, 1, count, stdout); } fwrite("\r", 1, 1, stdout); fclose(fp); } int main(int argc, char **argv) { char *root; root = getenv("ShellDirectory"); if (!root || !*root) { fprintf(stderr, "### Help - $ShellDirectory is not defined.\n"); return 1; } if (argc == 1) { help(root, "MPW"); } else { int i; for (i = 1; i < argc; ++i) { help(root, argv[i]); } } return 0; }

View File

@ -1,102 +0,0 @@
#ifdef __ORCAC__
#pragma optimize 79
#pragma noroot
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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;
}

View File

@ -1,20 +0,0 @@
#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

View File

@ -1,10 +0,0 @@
---
options:
- c: { argument : true }
- t: { argument : true }
help:
- SetFile [options] file...
- -c creator set the creator
- -t type set the file type

View File

@ -1,151 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <Finder.h>
#include <Files.h>
#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;
}

View File

@ -1,61 +0,0 @@
# makefile
Libraries=~/mpw/Libraries/Libraries
CLibraries=~/mpw/Libraries/CLibraries
# MPW 3.2
LIBS = \
$(Libraries)/Stubs.o \
$(CLibraries)/StdCLib.o \
$(Libraries)/Interface.o \
$(Libraries)/Runtime.o \
$(Libraries)/ToolLibs.o
LDFLAGS = -w -c 'MPS ' -t MPST \
-sn STDIO=Main -sn INTENV=Main -sn %A5Init=Main
# MPW 3.5
# LIBS = \
# $(CLibraries)/StdCLib.o \
# $(Libraries)/Stubs.o \
# $(Libraries)/IntEnv.o \
# $(Libraries)/MacRuntime.o \
# $(Libraries)/Interface.o \
# $(Libraries)/ToolLibs.o
# LDFLAGS = -d -c 'MPS ' -t MPST
all: Help GetEnv Duplicate SetFile
clean:
rm -f *.c.o
rm -f Help GetEnv Duplicate SetFile
GetEnv: GetEnv.c.o
mpw Link $(LDFLAGS) -o $@ $^ $(LIBS)
Help: Help.c.o
mpw Link $(LDFLAGS) -o $@ $^ $(LIBS)
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 $@
# GetEnv.c.o : GetEnv.c
# mpw SC -p GetEnv.c -o $@
# Help.c.o : Help.c
# mpw SC -p Help.c -o $@

View File

@ -1,44 +0,0 @@
#!/usr/bin/env ruby -w
#
# format
# -
# name # comment
#
file = nil
state = nil
#ARGF.binmode
#ARGF.set_encoding("BINARY")
ARGF.each { |line|
line.chomp!
case state
when nil
if line == '-'
state = :name
end
when :name
if line.match(/^([A-Za-z0-F]+)\s?#?/)
state = :data
filename = $1
file = File::new("Help.Files/#{filename}", "w")
#file.set_encoding("BINARY")
end
when :data
if line == '-'
state = :name
file = nil
else
file.puts(line)
end
end
}