All pastes #48770 Raw Edit

Unnamed

public text v1 · immutable
#48770 ·published 2006-04-09 17:34 UTC
rendered paste body
#include <sys/types.h> /* struct stat */
#include <sys/stat.h> /* stat() and S_ISDIR */
#include <stdio.h>
#include <string.h>
#include <errno.h>

int getopt(int argc, char * const argv[],
           const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;

const char *optstring = "+:d:e:";
const char *header = "REDSHIRT";
char *myname;

static void redshirt( FILE *fp );
static int testheader( FILE *fp, const char *fn );
static int shirtfile( const char *fn, const int direction );
static char *statfile( char *fn );
int main( int argc, char *argv[] );

static void
redshirt (FILE *fp)
{
	int j;
	if (fp == (const FILE *)NULL) return;

	errno = 0;
	j = fgetc(fp);
	while (j != EOF)
	{
		j = (j & 0x7F) + (~j & 0x80);
		(void) fputc(j, stdout);
		j = fgetc(fp);
	}
}

static int
testheader (FILE *fp, const char *fn)
{
	int ret;
	char *buf[9];
	if (fp == (const FILE *)0) return 0;
	if (fn == (const char *)0) return 0;
	errno = 0;

	ret = fread((void *)&buf, 1, 9, fp);
	if (ret == 9)
	{
		ret = memcmp((void *)buf, (void *)header, 9);
		if (ret < 0) ret = 1;
	}
	else if ((ret != EOF) || feof(fp)) ret = 1;
	if (ferror(fp)) ret = EOF;
	else if (ret) (void) fprintf(stderr,
			"%s: %s: Not a redshirt encrypted file\n", myname, fn);
	return !ret;
}

static int
shirtfile (const char *fn, const int direction)
{
	int ret;
	FILE *fp;
	if (fn == (const char *)0) return 1;
	ret = direction;
	fp = (FILE *)NULL;
	errno = 0;
	fp = fopen(fn, "r");
	if (fp != (FILE *)NULL)
	{
		if (ret) (void) fwrite((void *)header, 1, 9, stdout);
		else ret = testheader(fp, fn);
		if ((ret != EOF) && ret) redshirt(fp);
		ret = ferror(fp) != 0;
		if (ret) (void) fprintf(stderr,
				"%s: Could not read from file '%s': %s\n",
				myname, fn, strerror(errno));
		(void) fclose(fp);
	}
	 else
	{
		(void) fprintf(stderr,
			"%s: Could not open file '%s' for reading: %s\n",
			myname, fn, strerror(errno));
		ret = 1;
	}
	return ret;
}

static char *
statfile (char *fn)
{
	struct stat st;
	if (fn == (char *)0) return fn;
	(void) memset((void *)&st, 0, sizeof(struct stat));

	errno = 0;
	if (stat(fn, &st) == 0)
	{
		if (S_ISDIR(st.st_mode))
		{
			(void) fprintf(stderr, "%s: %s: Is a directory\n", myname, fn);
			fn = (char *)0;
		}
	}
	 else
	{
		(void) fprintf(stderr, "%s: %s: %s\n", myname, fn, strerror(errno));
		fn = (char *)0;
	}
	return fn;
}

int
main (int argc, char *argv[])
{
	int i;
	char *fn;
	myname = argv[0];
	opterr = 0;
	i = -1;
	fn = (char *)0;

	if (argc < 4) do
	{
		i = getopt(argc, argv, optstring);
		switch (i)
		{
			case 'd':
				fn = optarg;
				i = -2;
				break;
			case 'e':
				fn = optarg;
				i = -3;
			case -1:
				break;
			case '?':
				(void) fprintf(stderr, "%s: Unknown argument '%s'\n",
						argv[0], argv[optind-1]
						);
				i = -1;
				break;
			case ':':
				(void) fprintf(stderr, "%s: Missing argument\n", argv[0]);
			default:
				i = -1;
		}
	} while (i > 0);
	else (void) fprintf(stderr, "%s: Too many arguments\n", argv[0]);

	i = -i;
	i--;
	if (i) i = shirtfile(statfile(fn), --i);
	else (void) fprintf(stderr, "Usage: %s <-d|-e> <file>\n", argv[0]);

	return i;
}