summaryrefslogtreecommitdiff
path: root/data
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:30:07 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:30:07 -0800
commit5e0936b99e2d50769c5432b47c4d07c3dcdd37c6 (patch)
tree7ed686be807c3cce93be58daaf49169a94a21b04 /data
parent39c3e9d45c422c33aaf85c552a96434f2b9371e2 (diff)
downloadnetcat-5e0936b99e2d50769c5432b47c4d07c3dcdd37c6.tar.gz
auto import from //depot/cupcake/@135843
Diffstat (limited to 'data')
-rw-r--r--data/Makefile10
-rw-r--r--data/README9
-rw-r--r--data/data.c274
-rw-r--r--data/dns-any.d36
-rw-r--r--data/nfs-0.d59
-rw-r--r--data/pm.d8
-rw-r--r--data/pmap-dump.d60
-rw-r--r--data/pmap-mnt.d78
-rw-r--r--data/rip.d52
-rw-r--r--data/rservice.c68
-rw-r--r--data/showmount.d63
-rw-r--r--data/xor.c92
12 files changed, 809 insertions, 0 deletions
diff --git a/data/Makefile b/data/Makefile
new file mode 100644
index 0000000..65cf185
--- /dev/null
+++ b/data/Makefile
@@ -0,0 +1,10 @@
+all: data rservice xor
+
+data: data.c
+ cc -s -O -o data data.c
+rservice: rservice.c
+ cc -s -O -o rservice rservice.c
+xor: xor.c
+ cc -s -O -o xor xor.c
+clean:
+ rm -f *.o data rservice xor
diff --git a/data/README b/data/README
new file mode 100644
index 0000000..7e4b9fb
--- /dev/null
+++ b/data/README
@@ -0,0 +1,9 @@
+For now, read the header comments inside each of these for documentation.
+The programs are simple enough that they don't really need a Makefile any more
+complex than the one given; ymmv. Data and xor may also be useful on DOS,
+which is why there are hooks for it in the code.
+
+data.c a primitive atob / btoa byte generator
+*.d example input to "data -g"
+rservice.c a utility for scripting up rsh/rexec attacks
+xor.c generic xor handler
diff --git a/data/data.c b/data/data.c
new file mode 100644
index 0000000..56c167f
--- /dev/null
+++ b/data/data.c
@@ -0,0 +1,274 @@
+/* primitive arbitrary-data frontend for netcat. 0.9 960226
+ only handles one value per ascii line, but at least parses 0xNN too
+ an input line containing "%r" during "-g" generates a random byte
+
+ todo:
+ make work on msloss jus' for kicks [workin' on it...]
+
+ syntax: data -X [limit]
+ where X is one of
+ d: dump raw bytes to ascii format
+ g: generate raw bytes from ascii input
+ c: generate ??? of value -- NOTYET
+ r: generate all random bytes
+ and limit is how many bytes to generate or dump [unspecified = infinite]
+
+ *Hobbit*, started 951004 or so and randomly screwed around with since */
+
+#include <stdio.h>
+
+#ifdef MSDOS /* for MSC only at the moment... */
+#include <fcntl.h>
+#else /* MSDOS */
+#include <sys/file.h>
+#define HAVE_RANDOM /* XXX: might have to change */
+#endif /* MSDOS */
+
+static char buf_in [128];
+static char buf_raw [8192];
+static char surveysez[] = "survey sez... XXX\n";
+
+/* fgetss :
+ wrapper for fgets, that yanks trailing newlines. Doing the work ourselves
+ instead of calling strchr/strlen/whatever */
+char * fgetss (buf, len, from)
+ char * buf;
+ size_t len;
+ FILE * from;
+{
+ register int x;
+ register char * p, * q;
+ p = fgets (buf, len, from); /* returns ptr to buf */
+ if (! p)
+ return (NULL);
+ q = p;
+ for (x = 0; x < len; x++) {
+ *p = (*p & 0x7f); /* rip parity, just in case */
+ switch (*p) {
+ case '\n':
+ case '\r':
+ case '\0':
+ *p = '\0';
+ return (q);
+ } /* switch */
+ p++;
+ } /* for */
+} /* fgetss */
+
+/* randint:
+ swiped from rndb.c. Generates an INT, you have to mask down to char. */
+int randint()
+{
+ register int q;
+ register int x;
+
+#ifndef HAVE_RANDOM
+ q = rand();
+#else
+ q = random();
+#endif
+ x = ((q >> 8) & 0xff); /* perturb low byte using some higher bits */
+ x = q ^ x;
+ return (x);
+}
+
+main (argc, argv)
+ int argc;
+ char ** argv;
+{
+ register unsigned char * p;
+ register char * q;
+ register int x;
+ int bc = 0;
+ int limit = 0; /* num to gen, or 0 = infinite */
+ register int xlimit; /* running limit */
+ FILE * txt; /* line-by-line ascii file */
+ int raw; /* raw bytes fd */
+ int dumping = 0; /* cmd flags ... */
+ int genning = 0;
+ int randing = 0;
+
+ memset (buf_in, 0, sizeof (buf_in));
+ memset (buf_raw, 0, sizeof (buf_raw));
+
+ xlimit = 1; /* doubles as "exit flag" */
+ bc = 1; /* preload, assuming "dump" */
+ x = getpid() + 687319;
+/* if your library doesnt have srandom/random, use srand/rand. [from rnd.c] */
+#ifndef HAVE_RANDOM
+ srand (time(0) + x);
+#else
+ srandom (time(0) + x);
+#endif
+
+#ifdef O_BINARY
+/* DOS stupidity */
+/* Aha: *here's* where that setmode() lib call conflict in ?BSD came from */
+ x = setmode (0, O_BINARY); /* make stdin raw */
+ if (x < 0) {
+ fprintf (stderr, "stdin binary setmode oops: %d\n", x);
+ exit (1);
+ }
+ x = setmode (1, O_BINARY); /* make stdout raw */
+ if (x < 0) {
+ fprintf (stderr, "stdout binary setmode oops: %d\n", x);
+ exit (1);
+ }
+#endif /* O_BINARY */
+
+ if (argv[1]) {
+ p = argv[1]; /* shit-simple single arg parser... */
+ if (*p == '-') /* dash is optional, we'll deal */
+ p++;
+ if (*p == 'd')
+ dumping++;
+ if (*p == 'g')
+ genning++;
+ if (*p == 'r')
+ randing++;
+ } /* if argv 1 */
+
+/* optional second argument: limit # of bytes shoveled either way */
+ if (argv[2]) {
+ x = atoi (argv[2]);
+ if (x)
+ limit = x;
+ else
+ goto wrong;
+ xlimit = limit;
+ }
+
+/* Since this prog would likely best be written in assmbler, I'm gonna
+ write it *like* assembler. So there. */
+
+ if (randing)
+ goto do_rand;
+
+nextbuf: /* loop sleaze */
+
+ if (dumping) { /* switch off to wherever */
+ if (genning)
+ goto wrong;
+ goto do_dump;
+ }
+ if (genning)
+ goto do_gen;
+wrong:
+ fprintf (stderr, surveysez); /* if both or neither */
+ exit (1);
+
+do_gen:
+/* here if genning -- original functionality */
+ q = buf_raw;
+ bc = 0;
+/* suck up lines until eof or buf_raw is full */
+ while (1) {
+ p = fgetss (buf_in, 120, stdin);
+ if (! p)
+ break; /* EOF */
+/* super-primitive version first: one thingie per line */
+ if (*p == '#') /* comment */
+ continue;
+ if (*p == '\0') /* blank line */
+ continue;
+ if (*p == '%') { /* escape char? */
+ p++;
+ if (*p == 'r') { /* random byte */
+ x = randint();
+ goto stuff;
+ } /* %r */
+ } /* if "%" escape */
+ if (*p == '0')
+ if (*(p+1) == 'x') /* 0x?? */
+ goto hex;
+ x = atoi (p); /* reg'lar decimal number */
+ goto stuff;
+
+hex:
+/* A 65 a 97 */
+/* xxx: use a conversion table for this or something. Since we ripped the
+ parity bit, we only need a preset array of 128 with downconversion factors
+ loaded in *once*. maybe look at scanf... */
+ p++; p++; /* point at hex-chars */
+ x = 0;
+ if ((*p > 96) && (*p < 123)) /* a-z */
+ *p = (*p - 32); /* this is massively clumsy */
+ if ((*p > 64) && (*p < 71)) /* A-F */
+ x = (*p - 55);
+ if ((*p > 47) && (*p < 58)) /* digits */
+ x = (*p - 48);
+ p++;
+ if (*p) /* another digit? */
+ x = (x << 4); /* shift to hi half */
+ if ((*p > 96) && (*p < 123)) /* a-z */
+ *p = (*p - 32);
+ if ((*p > 64) && (*p < 71)) /* A-F */
+ x = (x | (*p - 55)); /* lo half */
+ if ((*p > 47) && (*p < 58)) /* digits */
+ x = (x | (*p - 48));
+
+/* fall thru */
+stuff: /* cvt to byte and add to buffer */
+ *q = (x & 0xff);
+ q++;
+ bc++;
+ if (limit) {
+ xlimit--;
+ if (xlimit == 0) /* max num reached */
+ break;
+ } /* limit */
+ if (bc >= sizeof (buf_raw)) /* buffer full */
+ break;
+ } /* while 1 */
+
+/* now in theory we have our buffer formed; shovel it out */
+ x = write (1, buf_raw, bc);
+ if (x <= 0) {
+ fprintf (stderr, "write oops: %d\n", x);
+ exit (1);
+ }
+ if (xlimit && p)
+ goto nextbuf; /* go get some more */
+ exit (0);
+
+do_dump:
+/* here if dumping raw stuff into an ascii file */
+/* gad, this is *so* much simpler! can we say "don't rewrite printf"? */
+ x = read (0, buf_raw, 8192);
+ if (x <= 0)
+ exit (0);
+ q = buf_raw;
+ for ( ; x > 0; x--) {
+ p = q;
+ printf ("%-3.3d # 0x%-2.2x # ", *p, *p);
+ if ((*p > 31) && (*p < 127))
+ printf ("%c %d\n", *p, bc);
+ else
+ printf (". %d\n", bc);
+ q++;
+ bc++;
+ if (limit) {
+ xlimit--;
+ if (xlimit == 0) {
+ fflush (stdout);
+ exit (0);
+ }
+ } /* limit */
+ } /* for */
+ goto nextbuf;
+
+do_rand:
+/* here if generating all-random bytes. Stays in this loop */
+ p = buf_raw;
+ while (1) {
+ *p = (randint() & 0xff);
+ write (1, p, 1); /* makes very slow! */
+ if (limit) {
+ xlimit--;
+ if (xlimit == 0)
+ break;
+ }
+ } /* while */
+ exit (0);
+
+} /* main */
diff --git a/data/dns-any.d b/data/dns-any.d
new file mode 100644
index 0000000..77b014c
--- /dev/null
+++ b/data/dns-any.d
@@ -0,0 +1,36 @@
+# dns "any for ." query, to udp 53
+# if tcp: precede with 2 bytes of len:
+# 0
+# 17
+# you should get at least *one* record back out
+
+# HEADER:
+0 # query id = 2
+2
+
+1 # flags/opcodes = query, dorecurse
+0
+
+0 # qdcount, i.e. nqueries: 1
+1
+
+0 # ancount: answers, 0
+0
+
+0 # nscount: 0
+0
+
+0 # addl records: 0
+0
+
+# end of fixed header
+
+0 # name-len: 0 for ".", lenbyte plus name-bytes otherwise
+
+0 # type: any, 255
+0xff
+
+0 # class: IN
+1
+
+# i think that's it..
diff --git a/data/nfs-0.d b/data/nfs-0.d
new file mode 100644
index 0000000..0360938
--- /dev/null
+++ b/data/nfs-0.d
@@ -0,0 +1,59 @@
+# UDP NFS null-proc call; finds active NFS listeners on port 2049.
+# If you get *something* back, there's an NFS server there.
+
+000 # XID: 4 trash bytes
+001
+002
+003
+
+000 # CALL: 0
+000
+000
+000
+
+000 # RPC version: 2
+000
+000
+002
+
+000 # nfs: 100003
+001
+0x86
+0xa3
+
+000 # version: 1
+000
+000
+001
+
+000 # procedure number: 0
+000
+000
+000
+
+000 # port: junk
+000
+000
+000
+
+000 # auth trash
+000
+000
+000
+
+000 # auth trash
+000
+000
+000
+
+000 # auth trash
+000
+000
+000
+
+000 # extra auth trash? probably not needed
+000
+000
+000
+
+# that's it!
diff --git a/data/pm.d b/data/pm.d
new file mode 100644
index 0000000..fe32769
--- /dev/null
+++ b/data/pm.d
@@ -0,0 +1,8 @@
+# obligatory duplicate of dr delete's Livingston portmaster crash, aka
+# telnet break. Fire into its telnet listener. An *old* bug by now, but
+# consider the small window one might obtain from a slightly out-of-rev PM
+# used as a firewall, that starts routing IP traffic BEFORE its filter sets
+# are fully loaded...
+
+255 # 0xff # . 1
+243 # 0xf3 # . 2
diff --git a/data/pmap-dump.d b/data/pmap-dump.d
new file mode 100644
index 0000000..bc6b632
--- /dev/null
+++ b/data/pmap-dump.d
@@ -0,0 +1,60 @@
+# portmap dump request: like "rpcinfo -p" but via UDP instead
+# send to UDP 111 and hope it's not a logging portmapper!
+# split into longwords, since rpc apparently only deals with them
+
+001 # 0x01 # . # XID: 4 trash bytes
+002 # 0x02 # .
+003 # 0x03 # .
+004 # 0x04 # .
+
+000 # 0x00 # . # MSG: int 0=call, 1=reply
+000 # 0x00 # .
+000 # 0x00 # .
+000 # 0x00 # .
+
+000 # 0x00 # . # pmap call body: rpc version=2
+000 # 0x00 # .
+000 # 0x00 # .
+002 # 0x02 # .
+
+000 # 0x00 # . # pmap call body: prog=PMAP, 100000
+001 # 0x01 # .
+134 # 0x86 # .
+160 # 0xa0 # .
+
+000 # 0x00 # . # pmap call body: progversion=2
+000 # 0x00 # .
+000 # 0x00 # .
+002 # 0x02 # .
+
+000 # 0x00 # . # pmap call body: proc=DUMP, 4
+000 # 0x00 # .
+000 # 0x00 # .
+004 # 0x04 # .
+
+# with AUTH_NONE, there are 4 zero integers [16 bytes] here
+
+000 # 0x00 # . # auth junk: cb_cred: auth_unix = 1; NONE = 0
+000 # 0x00 # .
+000 # 0x00 # .
+000 # 0x00 # .
+
+000 # 0x00 # . # auth junk
+000 # 0x00 # .
+000 # 0x00 # .
+000 # 0x00 # .
+
+000 # 0x00 # . # auth junk
+000 # 0x00 # .
+000 # 0x00 # .
+000 # 0x00 # .
+
+000 # 0x00 # . # auth junk
+000 # 0x00 # .
+000 # 0x00 # .
+000 # 0x00 # .
+
+# The reply you get back contains your XID, int 1 if "accepted", and
+# a whole mess of gobbledygook containing program numbers, versions,
+# and ports that rpcinfo knows how to decode. For the moment, you get
+# to wade through it yourself...
diff --git a/data/pmap-mnt.d b/data/pmap-mnt.d
new file mode 100644
index 0000000..00588ba
--- /dev/null
+++ b/data/pmap-mnt.d
@@ -0,0 +1,78 @@
+# portmap request for mountd [or whatever; see where prog=MOUNT]
+# send to UDP 111 and hope it's not a logging portmapper!
+# split into longwords, since rpc apparently only deals with them
+
+001 # 0x01 # . # XID: 4 trash bytes
+002 # 0x02 # .
+003 # 0x03 # .
+004 # 0x04 # .
+
+000 # 0x00 # . # MSG: int 0=call, 1=reply
+000 # 0x00 # .
+000 # 0x00 # .
+000 # 0x00 # .
+
+000 # 0x00 # . # pmap call body: rpc version=2
+000 # 0x00 # .
+000 # 0x00 # .
+002 # 0x02 # .
+
+000 # 0x00 # . # pmap call body: prog=PMAP, 100000
+001 # 0x01 # .
+134 # 0x86 # .
+160 # 0xa0 # .
+
+000 # 0x00 # . # pmap call body: progversion=2
+000 # 0x00 # .
+000 # 0x00 # .
+002 # 0x02 # .
+
+000 # 0x00 # . # pmap call body: proc=GETPORT, 3
+000 # 0x00 # .
+000 # 0x00 # .
+003 # 0x03 # .
+
+# with AUTH_NONE, there are 4 zero integers [16 bytes] here
+
+000 # 0x00 # . # auth junk: cb_cred: auth_unix = 1; NONE = 0
+000 # 0x00 # .
+000 # 0x00 # .
+000 # 0x00 # .
+
+000 # 0x00 # . # auth junk
+000 # 0x00 # .
+000 # 0x00 # .
+000 # 0x00 # .
+
+000 # 0x00 # . # auth junk
+000 # 0x00 # .
+000 # 0x00 # .
+000 # 0x00 # .
+
+000 # 0x00 # . # auth junk
+000 # 0x00 # .
+000 # 0x00 # .
+000 # 0x00 # .
+
+000 # 0x00 # . # prog=MOUNT, 100005
+001 # 0x01 # .
+134 # 0x86 # .
+165 # 0xa5 # .
+
+000 # 0x00 # . # progversion=1
+000 # 0x00 # .
+000 # 0x00 # .
+001 # 0x01 # .
+
+000 # 0x00 # . # protocol=udp, 17
+000 # 0x00 # .
+000 # 0x00 # .
+017 # 0x11 # .
+
+000 # 0x00 # . # proc num = junk
+000 # 0x00 # .
+000 # 0x00 # .
+000 # 0x00 # .
+
+# The reply you get back contains your XID, int 1 if "accepted", and
+# mountd's port number at the end or 0 if not registered.
diff --git a/data/rip.d b/data/rip.d
new file mode 100644
index 0000000..da505e2
--- /dev/null
+++ b/data/rip.d
@@ -0,0 +1,52 @@
+# struct netinfo {
+# struct sockaddr rip_dst; /* destination net/host */
+# int rip_metric; /* cost of route */
+# };
+# struct rip {
+# u_char rip_cmd; /* request/response */
+# u_char rip_vers; /* protocol version # */
+# u_char rip_res1[2]; /* pad to 32-bit boundary */
+# union {
+# struct netinfo ru_nets[1]; /* variable length... */
+# char ru_tracefile[1]; /* ditto ... */
+# } ripun;
+#define rip_nets ripun.ru_nets
+#define rip_tracefile ripun.ru_tracefile
+#define RIPCMD_REQUEST 1 /* want info */
+#define RIPCMD_RESPONSE 2 /* responding to request */
+#define RIPCMD_TRACEON 3 /* turn tracing on */
+#define RIPCMD_TRACEOFF 4 /* turn it off */
+#define HOPCNT_INFINITY 16 /* per Xerox NS */
+#define MAXPACKETSIZE 512 /* max broadcast size */
+
+### RIP packet redux
+### UDP send FROM clued-rtr/520 to target/520
+2 # RIPCMD_RESPONSE
+1 # version
+0 # padding
+0
+
+# sockaddr-plus-metric structs begin, as many as necessary...
+0 # len
+2 # AF_INET
+0 # port
+0
+# addr bytes:
+X
+Y
+Z
+Q
+0 # filler, out to 16 bytes [sizeof (sockaddr)] ...
+0
+0
+0
+0
+0
+0
+0
+0 # metric: net-order integer
+0
+0
+1
+
+## that's it
diff --git a/data/rservice.c b/data/rservice.c
new file mode 100644
index 0000000..1085d9c
--- /dev/null
+++ b/data/rservice.c
@@ -0,0 +1,68 @@
+/* generate ^@string1^@string2^@cmd^@ input to netcat, for scripting up
+ rsh/rexec attacks. Needs to be a prog because shells strip out nulls.
+
+ args:
+ locuser remuser [cmd]
+ remuser passwd [cmd]
+
+ cmd defaults to "pwd".
+
+ ... whatever. _H*/
+
+#include <stdio.h>
+
+/* change if you like; "id" is a good one for figuring out if you won too */
+static char cmd[] = "pwd";
+
+static char buf [256];
+
+main(argc, argv)
+ int argc;
+ char * argv[];
+{
+ register int x;
+ register int y;
+ char * p;
+ char * q;
+
+ p = buf;
+ memset (buf, 0, 256);
+
+ p++; /* first null */
+ y = 1;
+
+ if (! argv[1])
+ goto wrong;
+ x = strlen (argv[1]);
+ memcpy (p, argv[1], x); /* first arg plus another null */
+ x++;
+ p += x;
+ y += x;
+
+ if (! argv[2])
+ goto wrong;
+ x = strlen (argv[2]);
+ memcpy (p, argv[2], x); /* second arg plus null */
+ x++;
+ p += x;
+ y += x;
+
+ q = cmd;
+ if (argv[3])
+ q = argv[3];
+ x = strlen (q); /* not checked -- bfd */
+ memcpy (p, q, x); /* the command, plus final null */
+ x++;
+ p += x;
+ y += x;
+
+ memcpy (p, "\n", 1); /* and a newline, so it goes */
+ y++;
+
+ write (1, buf, y); /* zot! */
+ exit (0);
+
+wrong:
+ fprintf (stderr, "wrong! needs 2 or more args.\n");
+ exit (1);
+}
diff --git a/data/showmount.d b/data/showmount.d
new file mode 100644
index 0000000..499794b
--- /dev/null
+++ b/data/showmount.d
@@ -0,0 +1,63 @@
+# UDP mountd call. Use as input to find mount daemons and avoid portmap.
+# Useful proc numbers are 2, 5, and 6.
+# UDP-scan around between 600-800 to find most mount daemons.
+# Using this with "2", plugged into "nc -u -v -w 2 victim X-Y" will
+# directly scan *and* dump the current exports when mountd is hit.
+# combine stdout *and* stderr thru "strings" or something to clean it up
+
+000 # XID: 4 trash bytes
+001
+002
+003
+
+000 # CALL: 0
+000
+000
+000
+
+000 # RPC version: 2
+000
+000
+002
+
+000 # mount: 100005
+001
+0x86
+0xa5
+
+000 # mount version: 1
+000
+000
+001
+
+000 # procedure number -- put what you need here:
+000 # 2 = dump [showmount -e]
+000 # 5 = exportlist [showmount -a]
+xxx # "sed s/xxx/$1/ | data -g | nc ..." or some such...
+
+000 # port: junk
+000
+000
+000
+
+000 # auth trash
+000
+000
+000
+
+000 # auth trash
+000
+000
+000
+
+000 # auth trash
+000
+000
+000
+
+000 # extra auth trash? probably not needed
+000
+000
+000
+
+# that's it!
diff --git a/data/xor.c b/data/xor.c
new file mode 100644
index 0000000..9feead0
--- /dev/null
+++ b/data/xor.c
@@ -0,0 +1,92 @@
+/* Generic xor handler.
+
+ With no args, xors stdin against 0xFF to stdout. A single argument is a
+ file to read xor-bytes out of. Any zero in the xor-bytes array is treated
+ as the end; if you need to xor against a string that *includes* zeros,
+ you're on your own.
+
+ The indirect file can be generated easily with data.c.
+
+ Written because there are so many lame schemes for "masking" plaintext
+ passwords and the like floating around, and it's handy to just run an
+ obscure binary-format configuration file through this and look for strings.
+
+ *Hobbit*, 960208 */
+
+#include <stdio.h>
+#include <fcntl.h>
+
+char buf[8192];
+char bytes[256];
+char * py;
+
+/* do the xor, in place. Uses global ptr "py" to maintain "bytes" state */
+xorb (buf, len)
+ char * buf;
+ int len;
+{
+ register int x;
+ register char * pb;
+
+ pb = buf;
+ x = len;
+ while (x > 0) {
+ *pb = (*pb ^ *py);
+ pb++;
+ py++;
+ if (! *py)
+ py = bytes;
+ x--;
+ }
+} /* xorb */
+
+/* blah */
+main (argc, argv)
+ int argc;
+ char ** argv;
+{
+ register int x = 0;
+ register int y;
+
+/* manually preload; xor-with-0xFF is all too common */
+ memset (bytes, 0, sizeof (bytes));
+ bytes[0] = 0xff;
+
+/* if file named in any arg, reload from that */
+#ifdef O_BINARY /* DOS shit... */
+ x = setmode (0, O_BINARY); /* make stdin raw */
+ if (x < 0) {
+ fprintf (stderr, "stdin binary setmode oops: %d\n", x);
+ exit (1);
+ }
+ x = setmode (1, O_BINARY); /* make stdout raw */
+ if (x < 0) {
+ fprintf (stderr, "stdout binary setmode oops: %d\n", x);
+ exit (1);
+ }
+#endif /* O_BINARY */
+
+ if (argv[1])
+#ifdef O_BINARY
+ x = open (argv[1], O_RDONLY | O_BINARY);
+#else
+ x = open (argv[1], O_RDONLY);
+#endif
+ if (x > 0) {
+ read (x, bytes, 250); /* nothin' fancy here */
+ close (x);
+ }
+ py = bytes;
+ x = 1;
+ while (x > 0) {
+ x = read (0, buf, sizeof (buf));
+ if (x <= 0)
+ break;
+ xorb (buf, x);
+ y = write (1, buf, x);
+ if (y <= 0)
+ exit (1);
+ }
+ exit (0);
+}
+