Sunday, March 16, 2008

frob

Based on my comment earlier, I decided to write a frobbing program. It doesn't actually use memfrob, since it's limited to XORing with 42. This one's a bit more flexible.

frob.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#define BUFFLEN 1024

int main(int argc, char ** argv) {
char frobwith = 0, frobbase = 10, frobset = 0;
char buff[BUFFLEN];
int i = 0, x = 0, len = 0;
while((x = getopt(argc, argv, "b:f:h")) != -1) {
switch(x) {
case 'b':
if(frobset)
fprintf(stderr, "Base must be specified before the frobbing integer.\n");
else {
i = strtoul(optarg, NULL, 10);
if(!i) {
fprintf(stderr, "Can't use base-zero; defaulting to decimal.\n");
frobbase = 10;
}
else
frobbase = i;
}
break;
case 'f':
frobwith = strtoul(optarg, NULL, frobbase);
if(!frobwith)
fprintf(stderr, "Warning: frobbing with specified zero.\n");
frobset = 1;
break;
case 'h':
printf( "%s: frobbing a string with a chosen value.\n" \
"Options\n" \
"\t-b: The base to convert the frobbing argument with, default: 10\n" \
"\t\tMust be specified before the frobbing argument.\n" \
"\t-f: The frobbing argument, default: 0\n" \
"\t\tMust be between 0 and 255, or will go to default.\n" \
"\t-h: You specified it, so you must know that it goes to this help.\n", argv[0]);
return 255;
case '?':
if(optopt == 'b' || optopt == 'f')
fprintf(stderr, "Option %c requires an argument.\n", optopt);
else if(isprint(optopt))
fprintf(stderr, "Unknown option: -%c\n", optopt);
else
fprintf(stderr, "Argument FAIL: \\x%x", optopt);
return 1;
}
}
memset(buff, '\0', BUFFLEN);
while((len = read(0, buff, BUFFLEN - 1))) {
for(i = 0; i < len; i++)
putchar(buff[i] ^ frobwith);
memset(buff, '\0', len);
}
return 0;
}

Sample Run

% ./frob -h
./frob: frobbing a string with a chosen value.
Options
-b: The base to convert the frobbing argument with, default: 10
Must be specified before the frobbing argument.
-f: The frobbing argument, default: 0
Must be between 0 and 255, or will go to default.
-h: You specified it, so you must know that it goes to this help.
% echo 'foo bar baz' | ./frob -f 10
lee*hkx*hkp%
% echo 'foo bar baz' | ./frob -f 200
���誩�誩�%
% echo 'foo bar baz' | ./frob -f 255
���ߝ��ߝ��%

Please note that the percent symbol at the end of these lines is what ZSH outputs when the last output didn't end in a newline.

No comments: