File: command-line-args.c

package info (click to toggle)
hashrat 1.10.2-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 1,984 kB
  • sloc: ansic: 21,832; sh: 369; makefile: 187
file content (493 lines) | stat: -rw-r--r-- 23,457 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
#include "command-line-args.h"
#include "include-exclude.h"
#include "xattr.h"

CMDLINE CmdLine;



void HMACSetup(HashratCtx *Ctx)
{
char *Tempstr=NULL;
const char *ptr;
STREAM *S;

  ptr=GetVar(Ctx->Vars,"EncryptionKey");
  if (! StrValid(ptr))
  {
    if (isatty(0))
    {
      write(1, "Enter HMAC Key: ",16);

      S=STREAMFromFD(0);
      Tempstr=STREAMReadLine(Tempstr,S);
      StripTrailingWhitespace(Tempstr);
      SetVar(Ctx->Vars,"EncryptionKey",Tempstr);
      ptr=Tempstr;
      STREAMDestroy(S);
    }

    //By now we must have an encryption key!
    if (! StrValid(ptr))
    {
      write(1,"ERROR: No HMAC Key given!\n",27);
      exit(2);
    }
  }
Destroy(Tempstr);
}


//this function is called when a command-line switch has been recognized. It's told which flags to set
//and whether the switch takes a string argument, which it then reads and stores in the variable list
//with the name supplied in 'VarName'. 

void CommandLineHandleArg(int SetFlags, const char *VarName, const char *VarValue, ListNode *Vars)
{
const char *arg, *next;

	Flags |= SetFlags;
	
	arg=CommandLineCurr(&CmdLine);
	if (SetFlags & FLAG_NEXTARG)
	{
	next=CommandLineNext(&CmdLine);
	if (next==NULL)
	{
		printf("ERROR: The %s option requires an argument.\n",arg);
		exit(1);
	}
	else SetVar(Vars,VarName,next);
	}
	else if (StrValid(VarName)) SetVar(Vars,VarName,VarValue);
}



void CommandLineSetCtx(HashratCtx *Ctx, int Flag, int Encoding)
{
if (Encoding > 0) Ctx->Encoding=Encoding;

switch (Flag)
{
case CTX_INCLUDE:
case CTX_EXCLUDE:
case CTX_MTIME:
case CTX_MMIN:
case CTX_MYEAR:
 	IncludeExcludeAdd(Ctx, Flag, CommandLineNext(&CmdLine));
break;

default:
	Ctx->Flags |= Flag;
break;
}

}




void CommandLineHandleUpdate(HashratCtx *Ctx)
{
char *Token=NULL;
const char *ptr;

Flags |= FLAG_UPDATE;
ptr=CommandLineNext(&CmdLine);
ptr=GetToken(ptr,",",&Token,0);
while (ptr)
{
	if (strcasecmp(Token, "stderr")==0) Ctx->Aux=STREAMFromFD(2);
	else if (strcasecmp(Token, "xattr")==0) Ctx->Flags |= CTX_STORE_XATTR;
	else if (strcasecmp(Token, "txattr")==0) Ctx->Flags |= CTX_STORE_XATTR | CTX_XATTR_ROOT;
	else if (strcasecmp(Token, "memcached")==0) Ctx->Flags |= CTX_STORE_MEMCACHED;
	else if (strcasecmp(Token, "mcd")==0) Ctx->Flags |= CTX_STORE_MEMCACHED;
	else if (! Ctx->Aux) Ctx->Aux=STREAMFileOpen(Token, SF_WRONLY | SF_CREAT | SF_TRUNC);

ptr=GetToken(ptr,",",&Token,0);
}

Destroy(Token);
}


HashratCtx *CommandLineParseArg0()
{
HashratCtx *Ctx;
const char *ptr;

//Setup default context
Ctx=(HashratCtx *) calloc(1,sizeof(HashratCtx));
Ctx->Action=ACT_HASH;

//something went wrong with cmdline parsing
ptr=CommandLineCurr(&CmdLine);
if (! ptr) 
{
	Ctx->Action=ACT_PRINTUSAGE;
	return(Ctx);
}

Ctx->Vars=ListCreate();
Ctx->Out=STREAMFromFD(1);
SetVar(Ctx->Vars,"HashType","md5");


//argv[0] might be full path to the program, or just its name
ptr=GetBasename(ptr);

//if the program name is something other than 'hashrat', then we're being used as a drop-in
//replacement for another program. Change flags/behavior accordingly
if (strcmp(ptr,"md5sum")==0) 
CommandLineHandleArg(FLAG_TRAD_OUTPUT, "HashType", "md5",Ctx->Vars);
if (
		(strcmp(ptr,"sha1sum")==0) ||
		(strcmp(ptr,"shasum")==0) 
	) 
CommandLineHandleArg(FLAG_TRAD_OUTPUT, "HashType", "sha1",Ctx->Vars);
if (strcmp(ptr,"sha256sum")==0) CommandLineHandleArg(FLAG_TRAD_OUTPUT, "HashType", "sha256",Ctx->Vars);
if (strcmp(ptr,"sha512sum")==0) CommandLineHandleArg(FLAG_TRAD_OUTPUT, "HashType", "sha512",Ctx->Vars);
if (strcmp(ptr,"whirlpoolsum")==0) CommandLineHandleArg(FLAG_TRAD_OUTPUT, "HashType", "whirlpool",Ctx->Vars);
if (strcmp(ptr,"jh224sum")==0) CommandLineHandleArg(FLAG_TRAD_OUTPUT, "HashType", "jh-224",Ctx->Vars);
if (strcmp(ptr,"jh256sum")==0) CommandLineHandleArg(FLAG_TRAD_OUTPUT, "HashType", "jh-256",Ctx->Vars);
if (strcmp(ptr,"jh384sum")==0) CommandLineHandleArg(FLAG_TRAD_OUTPUT, "HashType", "jh-385",Ctx->Vars);
if (strcmp(ptr,"jh512sum")==0) CommandLineHandleArg(FLAG_TRAD_OUTPUT, "HashType", "jh-512",Ctx->Vars);


if (strcmp(ptr,"hashrat.cgi")==0) Ctx->Action=ACT_CGI;

return(Ctx);
}


//this is the main parsing function that goes through the command-line args
HashratCtx *CommandLineParseArgs(int argc, char *argv[])
{
char *Tempstr=NULL;
const char *ptr, *arg;
HashratCtx *Ctx;

CommandLineParserInit(&CmdLine, argc, argv);
Ctx=CommandLineParseArg0();


arg=CommandLineNext(&CmdLine);
while (arg)
{
if (
		(strcmp(arg,"-V")==0) ||
		(strcmp(arg,"--version")==0) ||
		(strcmp(arg,"-version")==0)
	)
{
	printf("version: %s\n",VERSION);
	return(NULL);
}
else if (
		(strcmp(arg,"--help")==0) ||
		(strcmp(arg,"-help")==0) ||
		(strcmp(arg,"-?")==0)
	)
{
	Ctx->Action=ACT_PRINTUSAGE;
	return(Ctx);
}
else if (strcmp(arg,"-C")==0)
{
	Ctx->Action = ACT_CHECK;
	CommandLineSetCtx(Ctx, CTX_RECURSE,0);
}
else if (strcmp(arg,"-Cf")==0)
{
	Ctx->Action = ACT_CHECK;
	CommandLineSetCtx(Ctx, CTX_RECURSE,0);
	CommandLineHandleArg(FLAG_OUTPUT_FAILS, "", "",Ctx->Vars);
}
else if (strcmp(arg,"-cf")==0)
{
	Ctx->Action = ACT_CHECK_LIST;
	CommandLineHandleArg(FLAG_OUTPUT_FAILS, "", "",Ctx->Vars);
}
else if (strcmp(arg,"-c")==0) Ctx->Action = ACT_CHECK_LIST;
else if (strcmp(arg,"-s")==0) Ctx->Action = ACT_SIGN;
else if (strcmp(arg,"-sign")==0) Ctx->Action = ACT_SIGN;
else if (strcmp(arg,"-cs")==0) Ctx->Action = ACT_CHECKSIGN;
else if (strcmp(arg,"-checksign")==0) Ctx->Action = ACT_CHECKSIGN;
else if (strcmp(arg,"-m")==0) Ctx->Action = ACT_FINDMATCHES;
else if (strcmp(arg,"-lm")==0) Ctx->Action = ACT_LOADMATCHES;
else if (strcmp(arg,"-dups")==0) Ctx->Action = ACT_FINDDUPLICATES;
else if (strcmp(arg,"-B")==0) Ctx->Action = ACT_BACKUP;
else if (strcmp(arg,"-cB")==0) Ctx->Action = ACT_CHECKBACKUP;
else if (strcmp(arg,"-cgi")==0) Ctx->Action = ACT_CGI;
else if (strcmp(arg,"-md5")==0) CommandLineHandleArg(0, "HashType", "md5",Ctx->Vars);
else if (strcmp(arg,"-sha")==0) CommandLineHandleArg(0, "HashType", "sha1",Ctx->Vars);
else if (strcmp(arg,"-sha1")==0) CommandLineHandleArg(0, "HashType", "sha1",Ctx->Vars);
else if (strcmp(arg,"-sha256")==0) CommandLineHandleArg(0, "HashType", "sha256",Ctx->Vars);
else if (strcmp(arg,"-sha512")==0) CommandLineHandleArg(0, "HashType", "sha512",Ctx->Vars);
else if (strcmp(arg,"-whirl")==0) CommandLineHandleArg(0, "HashType", "whirlpool",Ctx->Vars);
else if (strcmp(arg,"-whirlpool")==0) CommandLineHandleArg(0, "HashType", "whirlpool",Ctx->Vars);
else if (strcmp(arg,"-jh-224")==0) CommandLineHandleArg(0, "HashType", "jh-224",Ctx->Vars);
else if (strcmp(arg,"-jh-256")==0) CommandLineHandleArg(0, "HashType", "jh-256",Ctx->Vars);
else if (strcmp(arg,"-jh-384")==0) CommandLineHandleArg(0, "HashType", "jh-384",Ctx->Vars);
else if (strcmp(arg,"-jh-512")==0) CommandLineHandleArg(0, "HashType", "jh-512",Ctx->Vars);
else if (strcmp(arg,"-jh224")==0) CommandLineHandleArg(0, "HashType", "jh-224",Ctx->Vars);
else if (strcmp(arg,"-jh256")==0) CommandLineHandleArg(0, "HashType", "jh-256",Ctx->Vars);
else if (strcmp(arg,"-jh384")==0) CommandLineHandleArg(0, "HashType", "jh-384",Ctx->Vars);
else if (strcmp(arg,"-jh512")==0) CommandLineHandleArg(0, "HashType", "jh-512",Ctx->Vars);
else if (strcmp(arg,"-jh")==0) CommandLineHandleArg(0, "HashType", "jh-512",Ctx->Vars);
//else if (strcmp(argv[i],"-crc32")==0) CommandLineHandleArg(0, "HashType", "crc32",Ctx->Vars);
else if (strcmp(arg,"-8")==0)  CommandLineSetCtx(Ctx,  0, ENCODE_OCTAL);
else if (strcmp(arg,"-10")==0) CommandLineSetCtx(Ctx,  0, ENCODE_DECIMAL);
else if (strcmp(arg,"-16")==0) CommandLineSetCtx(Ctx,  0, ENCODE_HEX);
else if (strcmp(arg,"-H")==0)  CommandLineSetCtx(Ctx,  0, ENCODE_HEXUPPER);
else if (strcmp(arg,"-HEX")==0) CommandLineSetCtx(Ctx,  0, ENCODE_HEXUPPER);
else if (strcmp(arg,"-64")==0) CommandLineSetCtx(Ctx,  0, ENCODE_BASE64);
else if (strcmp(arg,"-base64")==0) CommandLineSetCtx(Ctx,  0, ENCODE_BASE64);
else if (strcmp(arg,"-i64")==0) CommandLineSetCtx(Ctx,  0, ENCODE_IBASE64);
else if (strcmp(arg,"-p64")==0) CommandLineSetCtx(Ctx,  0, ENCODE_PBASE64);
else if (strcmp(arg,"-x64")==0) CommandLineSetCtx(Ctx,  0, ENCODE_XXENC);
else if (strcmp(arg,"-u64")==0) CommandLineSetCtx(Ctx,  0, ENCODE_UUENC);
else if (strcmp(arg,"-g64")==0) CommandLineSetCtx(Ctx,  0, ENCODE_CRYPT);
else if (strcmp(arg,"-a85")==0) CommandLineSetCtx(Ctx,  0, ENCODE_ASCII85);
else if (strcmp(arg,"-z85")==0) CommandLineSetCtx(Ctx,  0, ENCODE_Z85);
else if (strcmp(arg,"-d")==0) CommandLineSetCtx(Ctx, CTX_DEREFERENCE,0);
else if (strcmp(arg,"-exe")==0) CommandLineSetCtx(Ctx, CTX_EXES,0);
else if (strcmp(arg,"-exec")==0) CommandLineSetCtx(Ctx, CTX_EXES,0);
else if (strcmp(arg,"-r")==0) CommandLineSetCtx(Ctx, CTX_RECURSE,0);
else if (strcmp(arg,"-fs")==0) CommandLineSetCtx(Ctx, CTX_ONE_FS,0);
else if (strcmp(arg,"-n")==0) CommandLineHandleArg(FLAG_NEXTARG, "Output:Length", "",Ctx->Vars);
else if (strcmp(arg,"-hmac")==0) CommandLineHandleArg(FLAG_NEXTARG | FLAG_HMAC, "EncryptionKey", "",Ctx->Vars);
else if (strcmp(arg,"-idfile")==0) CommandLineHandleArg(FLAG_NEXTARG,  "SshIdFile", "",Ctx->Vars);
else if (strcmp(arg,"-f")==0) CommandLineHandleArg(FLAG_NEXTARG, "ItemsListSource", "",Ctx->Vars);
else if (strcmp(arg,"-i")==0) CommandLineSetCtx(Ctx, CTX_INCLUDE,0);
else if (strcmp(arg,"-name")==0) CommandLineSetCtx(Ctx, CTX_INCLUDE,0);
else if (strcmp(arg,"-mtime")==0) CommandLineSetCtx(Ctx, CTX_MTIME,0);
else if (strcmp(arg,"-mmin")==0) CommandLineSetCtx(Ctx, CTX_MMIN,0);
else if (strcmp(arg,"-myear")==0) CommandLineSetCtx(Ctx, CTX_MYEAR,0);
else if (strcmp(arg,"-x")==0) CommandLineSetCtx(Ctx, CTX_EXCLUDE,0);
else if (strcmp(arg,"-X")==0) IncludeExcludeLoadExcludesFromFile(Ctx, CommandLineNext(&CmdLine));
else if (strcmp(arg,"-devmode")==0) CommandLineHandleArg(FLAG_DEVMODE, "", "",Ctx->Vars);
else if (strcmp(arg,"-lines")==0) CommandLineHandleArg(FLAG_LINEMODE, "", "",Ctx->Vars);
else if (strcmp(arg,"-rawlines")==0) CommandLineHandleArg(FLAG_RAW|FLAG_LINEMODE, "", "",Ctx->Vars);
else if (strcmp(arg,"-hide-input")==0) CommandLineHandleArg(FLAG_HIDE_INPUT, "", "",Ctx->Vars);
else if (strcmp(arg,"-star-input")==0) CommandLineHandleArg(FLAG_STAR_INPUT, "", "",Ctx->Vars);
else if (strcmp(arg,"-rl")==0) CommandLineHandleArg(FLAG_RAW|FLAG_LINEMODE, "", "",Ctx->Vars);
else if (strcmp(arg,"-xattr")==0) CommandLineHandleArg(FLAG_XATTR, "", "",Ctx->Vars);
else if (strcmp(arg,"-txattr")==0) CommandLineHandleArg(FLAG_TXATTR, "", "",Ctx->Vars);
else if (strcmp(arg,"-cache")==0) CommandLineSetCtx(Ctx, CTX_XATTR_CACHE,0);
else if (strcmp(arg,"-strict")==0) CommandLineHandleArg(FLAG_FULLCHECK, "", "",Ctx->Vars);
else if (strcmp(arg,"-color")==0) CommandLineHandleArg(FLAG_COLOR, "", "",Ctx->Vars);
else if (strcmp(arg,"-S")==0) CommandLineHandleArg(FLAG_FULLCHECK, "", "",Ctx->Vars);
else if (strcmp(arg,"-net")==0) CommandLineHandleArg(FLAG_NET, "", "",Ctx->Vars);
else if (strcmp(arg,"-memcached")==0) CommandLineHandleArg(FLAG_NEXTARG | FLAG_MEMCACHED, "Memcached:Server", "",Ctx->Vars);
else if (strcmp(arg,"-mcd")==0) CommandLineHandleArg(FLAG_NEXTARG | FLAG_MEMCACHED, "Memcached:Server", "",Ctx->Vars);
else if (strcmp(arg,"-xsel")==0) CommandLineHandleArg(FLAG_XSELECT, "", "",Ctx->Vars);
else if (strcmp(arg,"-v")==0) CommandLineHandleArg(FLAG_VERBOSE, "", "",Ctx->Vars);
else if ((strcmp(arg,"-dir")==0) || (strcmp(arg,"-dirmode")==0))
{
	Ctx->Action = ACT_HASHDIR;
	Ctx->Flags |= CTX_RECURSE;
}
else if ((strcmp(arg,"-hook")==0) || (strcmp(arg,"-h")==0))
{
	arg=CommandLineNext(&CmdLine);
	if (StrValid(arg)) DiffHook=CopyStr(DiffHook,arg);
	else 
	{
		printf("ERROR: No hook function supplied to -h/-hook switch (are you looking for help? Try --help or -?)\n");
		exit(1);
	}
}
else if (strcmp(arg,"-type")==0) 
{
	arg=CommandLineNext(&CmdLine);
	CommandLineHandleArg(0, "HashType", arg, Ctx->Vars);
}
else if (
					(strcmp(arg,"-t")==0) ||
					(strcmp(arg,"-trad")==0)
				) CommandLineHandleArg(FLAG_TRAD_OUTPUT, "", "",Ctx->Vars);
else if (
					(strcmp(arg,"-bsd")==0) ||
					(strcmp(arg,"-tag")==0) ||
					(strcmp(arg,"--tag")==0)
				) CommandLineHandleArg(FLAG_BSD_OUTPUT, "", "",Ctx->Vars);
else if (strcmp(arg,"-u")==0) CommandLineHandleUpdate(Ctx);
else if (strcmp(arg,"-attrs")==0) 
{
	arg=CommandLineNext(&CmdLine);
	if (StrValid(arg)) SetupXAttrList(arg);
	else printf("ERROR: No list of attribute names given to -attrs argument\n");
}
else 
{
Tempstr=QuoteCharsInStr(Tempstr, arg, ",");
Ctx->Targets=MCatStr(Ctx->Targets, Tempstr, ",", NULL);
}

arg=CommandLineNext(&CmdLine);
}

//The rest of this function finalizes setup based on what we parsed over all the command line


//if we're reading from a list file, then set appropriate action type
if (StrValid(GetVar(Ctx->Vars,"ItemsListSource"))) if (Ctx->Action==ACT_HASH) Ctx->Action=ACT_HASH_LISTFILE;


//if -hmac set, then upgrade hash type to the hmac version
if (Flags & FLAG_HMAC)
{
  Ctx->HashType=MCopyStr(Ctx->HashType,"hmac-",GetVar(Ctx->Vars,"HashType"),NULL);
  HMACSetup(Ctx);
}
else Ctx->HashType=CopyStr(Ctx->HashType,GetVar(Ctx->Vars,"HashType"));

switch (Ctx->Action)
{
case ACT_CHECK:
case ACT_CHECK_LIST:
	if (Flags & FLAG_XATTR) Ctx->Action=ACT_CHECK_XATTR;
	if (Flags & FLAG_MEMCACHED) Ctx->Action=ACT_CHECK_MEMCACHED;
break;

case ACT_HASH:
case ACT_HASH_LISTFILE:
	if (Flags & FLAG_XATTR) Ctx->Flags |= CTX_STORE_XATTR;
	if (Flags & FLAG_TXATTR) Ctx->Flags |= CTX_STORE_XATTR | CTX_XATTR_ROOT;
	if (Flags & FLAG_MEMCACHED) Ctx->Flags |= CTX_STORE_MEMCACHED;
break;

case ACT_FINDMATCHES:
	if (Flags & FLAG_MEMCACHED) Ctx->Action=ACT_FINDMATCHES_MEMCACHED;
break;


}

if (Ctx->Encoding==0) Ctx->Encoding=ENCODE_HEX;

//if no path given, then force to '-' for 'standard in'
ptr=GetVar(Ctx->Vars,"Path");
if (! StrValid(ptr)) SetVar(Ctx->Vars,"Path","-");

Destroy(Tempstr);
return(Ctx);
}



void CommandLinePrintUsage()
{
printf("Hashrat: version %s\n",VERSION);
printf("Author: Colum Paget\n");
printf("Email: colums.projects@gmail.com\n");
printf("Credits:\n");
printf("	Thanks for bug reports/advice to: Stephan Hegel, Michael Shigorin <mike@altlinux.org> and Joao Eriberto Mota Filho <eriberto@debian.org>\n");
printf("	Thanks to the people who invented the hash functions!\n	MD5: Ronald Rivest\n	Whirlpool: Vincent Rijmen, Paulo S. L. M. Barreto\n	JH: Hongjun Wu\n	SHA: The NSA (thanks, but please stop reading my email. It's kinda creepy.).\n\n"); 

printf("	Special thanks to Professor Hongjun Wu for taking the time to confirm that his JH algorithm is free for use in GPL programs.\n");

printf("	Special, special thanks to Joao Eriberto Mota Filho for doing a LOT of work to make hashrat debian ready!\n");

printf("\n");
printf("Usage:\n    hashrat [options] [path to hash]...\n");
printf("\n    hashrat -c [options] [input file of hashes]...\n\n");

printf("Options:\n");
printf("  %-15s %s\n","--help", "Print this help");
printf("  %-15s %s\n","-help", "Print this help");
printf("  %-15s %s\n","-?", "Print this help");
printf("  %-15s %s\n","--version", "Print program version");
printf("  %-15s %s\n","-version", "Print program version");
printf("  %-15s %s\n","-md5", "Use md5 hash algorithmn");
printf("  %-15s %s\n","-sha1", "Use sha1 hash algorithmn");
printf("  %-15s %s\n","-sha256", "Use sha256 hash algorithmn");
printf("  %-15s %s\n","-sha512", "Use sha512 hash algorithmn");
printf("  %-15s %s\n","-whirl", "Use whirlpool hash algorithmn");
printf("  %-15s %s\n","-whirlpool", "Use whirlpool hash algorithmn");
printf("  %-15s %s\n","-jh224", "Use jh-224 hash algorithmn");
printf("  %-15s %s\n","-jh256", "Use jh-256 hash algorithmn");
printf("  %-15s %s\n","-jh384", "Use jh-384 hash algorithmn");
printf("  %-15s %s\n","-jh512", "Use jh-512 hash algorithmn");
printf("  %-15s %s\n","-hmac", "HMAC using specified hash algorithm");
printf("  %-15s %s\n","-8", "Encode with octal instead of hex");
printf("  %-15s %s\n","-10", "Encode with decimal instead of hex");
printf("  %-15s %s\n","-H", "Encode with UPPERCASE hexadecimal");
printf("  %-15s %s\n","-HEX", "Encode with UPPERCASE hexadecimal");
printf("  %-15s %s\n","-64", "Encode with base64 instead of hex");
printf("  %-15s %s\n","-base64", "Encode with base64 instead of hex");
printf("  %-15s %s\n","-i64", "Encode with base64 with rearranged characters");
printf("  %-15s %s\n","-p64", "Encode with base64 with a-z,A-Z and _-, for best compatibility with 'allowed characters' in websites.");
printf("  %-15s %s\n","-x64", "Encode with XXencode style base64.");
printf("  %-15s %s\n","-u64", "Encode with UUencode style base64.");
printf("  %-15s %s\n","-g64", "Encode with GEDCOM style base64.");
printf("  %-15s %s\n","-a85", "Encode with ASCII85.");
printf("  %-15s %s\n","-z85", "Encode with ZEROMQ variant of ASCII85.");
printf("  %-15s %s\n","-t", "Output hashes in traditional md5sum, shaXsum format");
printf("  %-15s %s\n","-trad", "Output hashes in traditional md5sum, shaXsum format");
printf("  %-15s %s\n","-bsd", "Output hashes in bsdsum format");
printf("  %-15s %s\n","-tag", "Output hashes in bsdsum format");
printf("  %-15s %s\n","--tag", "Output hashes in bsdsum format");
printf("  %-15s %s\n","-r", "Recurse into directories when hashing files");
printf("  %-15s %s\n","-f <listfile>", "Hash files listed in <listfile>");
printf("  %-15s %s\n","-i <patterns>", "Only hash items matching a comma-seperated list of shell patterns");
printf("  %-15s %s\n","-x <patterns>", "Exclude items matching a comma-sepearted list of shell patterns");
printf("  %-15s %s\n","-X <file>", "Exclude items matching shell patters stored in <file>");
printf("  %-15s %s\n","-name  <patterns>", "Only hash items matching a comma-seperated list of shell patterns (-name aka 'find')");
printf("  %-15s %s\n","-mtime <days>", "Only hash items <days> old. Has the same format as the find command, e.g. -10 is younger than ten days, +10 is older than ten, and 10 is ten days old");
printf("  %-15s %s\n","-mmin  <mins>", "Only hash items <min> minutes old. Has the same format as the find command, e.g. -10 is younger than ten mins, +10 is older than ten, and 10 is ten mins old");
printf("  %-15s %s\n","-myear <years>", "Only hash items <years> old. Has the same format as the find command, e.g. -10 is younger than ten years, +10 is older than ten, and 10 is ten years old");
printf("  %-15s %s\n","-exec", "In CHECK or MATCH mode only examine executable files.");
printf("  %-15s %s\n","-dups", "Search for duplicate files.");
printf("  %-15s %s\n","-n <length>", "Truncate hashes to <length> bytes");
printf("  %-15s %s\n","-c", "CHECK hashes against list from file (or stdin)");
printf("  %-15s %s\n","-cf", "CHECK hashes against list but only show failures");
printf("  %-15s %s\n","-C <dir>", "Recursively CHECK directory against list of files on stdin ");
printf("  %-15s %s\n","-Cf <dir>", "Recursively CHECK directory against list but only show failures");
printf("  %-15s %s\n","-m", "MATCH files from a list read from stdin.");
printf("  %-15s %s\n","-lm", "Read hashes from stdin, upload them to a memcached server (requires the -memcached option).");
printf("  %-15s %s\n","-memcached <server>", "Specify memcached server. (Overrides reading list from stdin if used with -m, -c or -cf).");
printf("  %-15s %s\n","-mcd <server>", "Specify memcached server. (Overrides reading list from stdin if used with -m, -c or -cf).");
printf("  %-15s %s\n","-h <script>", "Script to run when a file fails CHECK mode, or is found in MATCH mode.");
printf("  %-15s %s\n","-hook <script>", "Script to run when a file fails CHECK mode, or is found in FIND mode");
printf("  %-15s %s\n","-color", "Use ANSI color codes on output when checking hashes.");
printf("  %-15s %s\n","-strict", "Strict mode: when checking, check file mtime, owner, group, and inode as well as it's hash");
printf("  %-15s %s\n","-S", "Strict mode: when checking, check file mtime, owner, group, and inode as well as it's hash");
printf("  %-15s %s\n","-d","dereference (follow) symlinks"); 
printf("  %-15s %s\n","-fs", "Stay on one file system");
printf("  %-15s %s\n","-dir", "DirMode: Read all files in directory and create one hash for them!");
printf("  %-15s %s\n","-dirmode", "DirMode: Read all files in directory and create one hash for them!");
printf("  %-15s %s\n","-devmode", "DevMode: read from a file EVEN OF IT'S A DEVNODE");
printf("  %-15s %s\n","-lines", "Read lines from stdin and hash each line independently.");
printf("  %-15s %s\n","-rawlines", "Read lines from stdin and hash each line independently, INCLUDING any trailing whitespace. (This is compatible with 'echo text | md5sum')");
printf("  %-15s %s\n","-rl", "Read lines from stdin and hash each line independently, INCLUDING any trailing whitespace. (This is compatible with 'echo text | md5sum')");
printf("  %-15s %s\n","-cgi", "Run in HTTP CGI mode");
printf("  %-15s %s\n","-net", "Treat 'file' arguments as either ssh or http URLs, and pull files over the network and then hash them (Allows hashing of files on remote machines).");
printf("  %-15s %s\n","", "URLs are in the format ssh://[username]:[password]@[host]:[port] or http://[username]:[password]@[host]:[port]..");
printf("  %-15s %s\n","-idfile <path>", "Path to an ssh private key file to use to authenticate INSTEAD OF A PASSWORD when pulling files via ssh.");
printf("  %-15s %s\n","-xattr", "Use eXtended file ATTRibutes. In hash mode, store hashes in the file attributes, in check mode compare against hashes stored in file attributes.");
printf("  %-15s %s\n","-txattr", "Use TRUSTED eXtended file ATTRibutes. In hash mode, store hashes in 'trusted' file attributes. 'trusted' attributes can only be read and written by root. Under freebsd this menas SYSTEM attributes.");
printf("  %-15s %s\n","-attrs", "comma-separated list of filesystem attribute names to be set to the value of the hash.");
printf("  %-15s %s\n","-cache", "Use hashes stored in 'user' xattr if they're younger than the mtime of the file. This speeds up outputting hashes.");
printf("  %-15s %s\n","-u <types>", "Update. In checking mode, update hashes for the files as you go. <types> is a comma-separated list of things to update, which can be 'xattr' 'memcached' or a file name. This will update these targets with the hash that was found at the time of checking.");
printf("  %-15s %s\n","-hide-input", "When reading data from stdin in linemode, set the terminal to not echo characters, thus hiding typed input.");
printf("  %-15s %s\n","-star-input", "When reading data from stdin in linemode replace characters with stars.");
printf("  %-15s %s\n","-xsel", "Update X11 clipboard and primary selections to the current hash. This works using Xterm command sequences. The xterm resource 'allowWindowOps' must be set to 'true' for this to work.");

printf("\n\nHashrat can also detect if it's being run under any of the following names (e.g., via symlinks)\n\n");
printf("  %-15s %s\n","md5sum","run with '-trad -md5'");
printf("  %-15s %s\n","shasum","run with '-trad -sha1'");
printf("  %-15s %s\n","sha1sum","run with '-trad -sha1'");
printf("  %-15s %s\n","sha256sum","run with '-trad -sha256'");
printf("  %-15s %s\n","sha512sum","run with '-trad -sha512'");
printf("  %-15s %s\n","jh224sum","run with '-trad -jh224'");
printf("  %-15s %s\n","jh256sum","run with '-trad -jh256'");
printf("  %-15s %s\n","jh384sum","run with '-trad -jh384'");
printf("  %-15s %s\n","jh512sum","run with '-trad -jh512'");
printf("  %-15s %s\n","whirlpoolsum","run with '-trad -whirl'");
printf("  %-15s %s\n","hashrat.cgi","run in web-enabled 'cgi mode'");
}