Category : OS/2 Files
Archive   : EMXTST8F.ZIP
Filename : EATOOL.C
#define INCL_DOSFILEMGR
#include
#include
#include
#include
#include
#include
#include
#include
#define FALSE 0
#define TRUE 1
enum actions
{
ACTION_NONE,
ACTION_ADD,
ACTION_DISCARD,
ACTION_LIST,
ACTION_GET,
ACTION_MERGE,
ACTION_PUT,
ACTION_REMOVE
};
static int debugging = FALSE;
static enum actions action = ACTION_NONE;
static _ead empty_ead = NULL;
static void do_add (const char *path, const char *name, const char *value)
{
int i, size;
_ead ead;
char *buf, *uname;
uname = strdup (name);
if (uname == NULL)
{
fprintf (stderr, "Out of memory\n");
exit (2);
}
_nls_strupr (uname);
ead = _ead_create ();
if (ead == NULL)
{
perror (NULL);
exit (2);
}
size = strlen (value);
buf = malloc (size + 4);
if (buf == NULL)
{
fprintf (stderr, "Out of memory\n");
exit (2);
}
((USHORT *)buf)[0] = EAT_ASCII;
((USHORT *)buf)[1] = size;
memcpy (buf+4, value, size);
if (_ead_add (ead, uname, 0, buf, size+4) < 0)
{
perror (path);
exit (2);
}
if (strcmp (path, "-") == 0)
i = _ead_write (ead, NULL, fileno (stdout), _EAD_MERGE);
else
i = _ead_write (ead, path, 0, _EAD_MERGE);
if (i < 0)
perror (path);
free (buf); free (uname);
_ead_destroy (ead);
}
static void do_remove (const char *path, const char *name)
{
_ead ead;
int i;
char *uname;
ead = _ead_create ();
if (ead == NULL)
{
perror (NULL);
exit (2);
}
uname = strdup (name);
if (uname == NULL)
{
fprintf (stderr, "Out of memory\n");
exit (2);
}
_nls_strupr (uname);
if (_ead_read (ead, path, 0, 0) < 0)
perror (path);
i = _ead_find (ead, uname);
if (i < 0)
{
perror (path);
exit (2);
}
if (_ead_delete (ead, i) < 0)
{
perror ("_ead_delete");
exit (2);
}
if (_ead_write (ead, path, 0, 0) < 0)
perror (path);
free (uname);
_ead_destroy (ead);
}
static void do_discard (const char *path)
{
int i;
if (empty_ead == NULL)
{
empty_ead = _ead_create ();
if (empty_ead == NULL)
{
perror (NULL);
exit (2);
}
}
if (strcmp (path, "-") == 0)
i = _ead_write (empty_ead, NULL, fileno (stdout), 0);
else
i = _ead_write (empty_ead, path, 0, 0);
if (i < 0)
perror (path);
}
static void do_list (const char *path)
{
_ead ead;
int i, n, nlen, vsize;
const char *name, *value;
ead = _ead_create ();
if (ead == NULL)
{
perror (NULL);
exit (2);
}
if (strcmp (path, "-") == 0)
i = _ead_read (ead, NULL, fileno (stdin), 0);
else
i = _ead_read (ead, path, 0, 0);
if (i < 0)
perror (path);
else
{
if (debugging)
printf ("%s (%d %d %d):\n", path,
_ead_name_len (ead, 0), _ead_value_size (ead, 0),
_ead_fea2list_size (ead));
else
printf ("%s:\n", path);
_ead_sort (ead);
n = _ead_count (ead);
for (i = 1; i <= n; ++i)
{
name = _ead_get_name (ead, i);
if (name == NULL)
perror (path);
else
{
vsize = _ead_value_size (ead, i);
if (vsize < 0) perror (path);
if (debugging)
{
nlen = _ead_name_len (ead, i);
if (nlen < 0) perror (path);
printf (" %s (%d): ", name, nlen);
}
else
printf (" %s: ", name);
if (vsize >= 4)
{
value = _ead_get_value (ead, i);
if (value == NULL)
perror (path);
else
switch (*(USHORT *)value)
{
case EAT_ASCII:
printf ("\"");
fwrite (value+4, vsize-4, 1, stdout);
printf ("\"\n");
break;
case EAT_BINARY:
printf ("%d bytes of binary data\n", vsize);
break;
case EAT_BITMAP:
printf ("%d bytes of bitmap data\n", vsize);
break;
case EAT_METAFILE:
printf ("%d bytes of metafile data\n", vsize);
break;
case EAT_ICON:
printf ("%d bytes of icon data\n", vsize);
break;
case EAT_EA:
printf ("%d bytes of associated data\n", vsize);
break;
case EAT_MVMT:
case EAT_MVST:
case EAT_ASN1:
printf ("%d bytes of multivalue data\n", vsize);
break;
default:
printf ("%d bytes\n", vsize);
break;
}
}
else
printf ("%d bytes\n", vsize);
}
}
_ead_destroy (ead);
}
}
static void do_put (const char *path, const char *hold)
{
_ead ead;
int i;
PFEALIST pfealist;
const FEA2LIST *pfea2list;
FILE *hold_file;
ead = _ead_create ();
if (ead == NULL)
{
perror (NULL);
exit (2);
}
if (strcmp (path, "-") == 0)
i = _ead_read (ead, NULL, fileno (stdin), 0);
else
i = _ead_read (ead, path, 0, 0);
if (i < 0)
perror (path);
else
{
hold_file = fopen (hold, "wb");
if (hold_file == NULL)
{
perror (hold);
exit (2);
}
pfea2list = _ead_get_fea2list (ead);
if (pfea2list != NULL)
{
pfealist = _ead_fea2list_to_fealist (pfea2list);
fwrite (pfealist, pfealist->cbList, 1, hold_file);
free (pfealist);
}
if (fflush (hold_file) != 0 || fclose (hold_file) != 0)
{
perror (hold);
exit (2);
}
_ead_destroy (ead);
}
}
static void do_get (const char *path, const char *hold, int merge)
{
int i, wflag;
FILE *f;
long size;
PFEALIST pfealist;
PFEA2LIST pfea2list;
_ead ead;
ead = _ead_create ();
if (ead == NULL)
{
perror (NULL);
exit (2);
}
f = fopen (hold, "rb");
if (f == NULL)
{
perror (hold);
exit (2);
}
size = filelength (fileno (f));
if (size == -1)
{
perror (hold);
exit (2);
}
if (size != 0)
{
pfealist = malloc (size);
if (pfealist == NULL)
{
fprintf (stderr, "Out of memory\n");
exit (2);
}
if (fread (pfealist, size, 1, f) != 1)
{
if (ferror (f))
perror (hold);
else
fprintf (stderr, "%s: end of file reached\n", hold);
exit (2);
}
free (pfealist);
pfea2list = _ead_fealist_to_fea2list (pfealist);
if (pfea2list == NULL)
{
perror (NULL);
exit (2);
}
if (_ead_use_fea2list (ead, pfea2list) != 0)
{
perror (NULL);
exit (2);
}
free (pfea2list);
}
fclose (f);
wflag = (merge ? _EAD_MERGE : 0);
if (strcmp (path, "-") == 0)
i = _ead_write (ead, NULL, fileno (stdout), wflag);
else
i = _ead_write (ead, path, 0, wflag);
if (i < 0)
{
perror (path);
exit (2);
}
_ead_destroy (ead);
}
static void usage (void)
{
fputs ("Usage: eatool -g
fputs (" eatool -m
fputs (" eatool -p
fputs (" eatool -d
fputs (" eatool -l [-z]
fputs (" eatool -a
fputs (" eatool -r
fputs ("Options:\n", stderr);
fputs (" -a Add extended attribute\n", stderr);
fputs (" -d Discard extended attributes\n", stderr);
fputs (" -g Get extended attributes from holdfile\n", stderr);
fputs (" -m Merge extended attributes from holdfile\n", stderr);
fputs (" -l List extended attributes\n", stderr);
fputs (" -p Put extended attributes into holdfile\n", stderr);
fputs (" -r Remove extended attribute\n", stderr);
fputs (" -z Turn on debugging output\n", stderr);
exit (1);
}
static void set_action (enum actions a)
{
if (action != ACTION_NONE)
usage ();
action = a;
}
static void apply (int argc, char *argv[], void (*function)(const char *path))
{
int i, j;
char **list;
for (i = optind; i < argc; ++i)
{
list = _fnexplode (argv[i]);
if (list == NULL)
function (argv[i]);
else
{
for (j = 0; list[j] != NULL; ++j)
function (list[j]);
_fnexplodefree (list);
}
}
}
int main (int argc, char *argv[])
{
int c;
opterr = FALSE;
while ((c = getopt (argc, argv, "adglmprz")) != EOF)
{
switch (c)
{
case 'a':
set_action (ACTION_ADD);
break;
case 'd':
set_action (ACTION_DISCARD);
break;
case 'g':
set_action (ACTION_GET);
break;
case 'm':
set_action (ACTION_MERGE);
break;
case 'l':
set_action (ACTION_LIST);
break;
case 'p':
set_action (ACTION_PUT);
break;
case 'r':
set_action (ACTION_REMOVE);
break;
case 'z':
debugging = TRUE;
break;
default:
usage ();
}
}
_nls_init ();
switch (action)
{
case ACTION_ADD:
if (argc - optind != 3)
usage ();
do_add (argv[optind+0], argv[optind+1], argv[optind+2]);
break;
case ACTION_DISCARD:
apply (argc, argv, do_discard);
break;
case ACTION_GET:
case ACTION_MERGE:
if (argc - optind != 2)
usage ();
do_get (argv[optind+0], argv[optind+1], action == ACTION_MERGE);
break;
case ACTION_LIST:
apply (argc, argv, do_list);
break;
case ACTION_PUT:
if (argc - optind != 2)
usage ();
do_put (argv[optind+0], argv[optind+1]);
break;
case ACTION_REMOVE:
if (argc - optind != 2)
usage ();
do_remove (argv[optind+0], argv[optind+1]);
break;
default:
usage ();
}
return (0);
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/