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;
}