1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate */
5*7c478bd9Sstevel@tonic-gate
6*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
7*7c478bd9Sstevel@tonic-gate
8*7c478bd9Sstevel@tonic-gate /*
9*7c478bd9Sstevel@tonic-gate * This program is copyright Alec Muffett 1993. The author disclaims all
10*7c478bd9Sstevel@tonic-gate * responsibility or liability with respect to it's usage or its effect
11*7c478bd9Sstevel@tonic-gate * upon hardware or computer systems, and maintains copyright as set out
12*7c478bd9Sstevel@tonic-gate * in the "LICENCE" document which accompanies distributions of Crack v4.0
13*7c478bd9Sstevel@tonic-gate * and upwards.
14*7c478bd9Sstevel@tonic-gate */
15*7c478bd9Sstevel@tonic-gate
16*7c478bd9Sstevel@tonic-gate #include "packer.h"
17*7c478bd9Sstevel@tonic-gate
18*7c478bd9Sstevel@tonic-gate
19*7c478bd9Sstevel@tonic-gate #define RULE_NOOP ':'
20*7c478bd9Sstevel@tonic-gate #define RULE_PREPEND '^'
21*7c478bd9Sstevel@tonic-gate #define RULE_APPEND '$'
22*7c478bd9Sstevel@tonic-gate #define RULE_REVERSE 'r'
23*7c478bd9Sstevel@tonic-gate #define RULE_UPPERCASE 'u'
24*7c478bd9Sstevel@tonic-gate #define RULE_LOWERCASE 'l'
25*7c478bd9Sstevel@tonic-gate #define RULE_PLURALISE 'p'
26*7c478bd9Sstevel@tonic-gate #define RULE_CAPITALISE 'c'
27*7c478bd9Sstevel@tonic-gate #define RULE_DUPLICATE 'd'
28*7c478bd9Sstevel@tonic-gate #define RULE_REFLECT 'f'
29*7c478bd9Sstevel@tonic-gate #define RULE_SUBSTITUTE 's'
30*7c478bd9Sstevel@tonic-gate #define RULE_MATCH '/'
31*7c478bd9Sstevel@tonic-gate #define RULE_NOT '!'
32*7c478bd9Sstevel@tonic-gate #define RULE_LT '<'
33*7c478bd9Sstevel@tonic-gate #define RULE_GT '>'
34*7c478bd9Sstevel@tonic-gate #define RULE_EXTRACT 'x'
35*7c478bd9Sstevel@tonic-gate #define RULE_OVERSTRIKE 'o'
36*7c478bd9Sstevel@tonic-gate #define RULE_INSERT 'i'
37*7c478bd9Sstevel@tonic-gate #define RULE_EQUALS '='
38*7c478bd9Sstevel@tonic-gate #define RULE_PURGE '@'
39*7c478bd9Sstevel@tonic-gate #define RULE_CLASS '?' /* class rule? socialist ethic in cracker? */
40*7c478bd9Sstevel@tonic-gate #define RULE_DFIRST '['
41*7c478bd9Sstevel@tonic-gate #define RULE_DLAST ']'
42*7c478bd9Sstevel@tonic-gate #define RULE_MFIRST '('
43*7c478bd9Sstevel@tonic-gate #define RULE_MLAST ')'
44*7c478bd9Sstevel@tonic-gate
45*7c478bd9Sstevel@tonic-gate int
Suffix(char * myword,char * suffix)46*7c478bd9Sstevel@tonic-gate Suffix(char *myword, char *suffix)
47*7c478bd9Sstevel@tonic-gate {
48*7c478bd9Sstevel@tonic-gate register int i;
49*7c478bd9Sstevel@tonic-gate register int j;
50*7c478bd9Sstevel@tonic-gate
51*7c478bd9Sstevel@tonic-gate i = strlen(myword);
52*7c478bd9Sstevel@tonic-gate j = strlen(suffix);
53*7c478bd9Sstevel@tonic-gate
54*7c478bd9Sstevel@tonic-gate if (i > j) {
55*7c478bd9Sstevel@tonic-gate return (STRCMP((myword + i - j), suffix));
56*7c478bd9Sstevel@tonic-gate } else {
57*7c478bd9Sstevel@tonic-gate return (-1);
58*7c478bd9Sstevel@tonic-gate }
59*7c478bd9Sstevel@tonic-gate }
60*7c478bd9Sstevel@tonic-gate
61*7c478bd9Sstevel@tonic-gate char *
Reverse(register char * str)62*7c478bd9Sstevel@tonic-gate Reverse(register char *str) /* return a pointer to a reversal */
63*7c478bd9Sstevel@tonic-gate {
64*7c478bd9Sstevel@tonic-gate register int i;
65*7c478bd9Sstevel@tonic-gate register int j;
66*7c478bd9Sstevel@tonic-gate static char area[PATH_MAX];
67*7c478bd9Sstevel@tonic-gate
68*7c478bd9Sstevel@tonic-gate j = i = strlen(str);
69*7c478bd9Sstevel@tonic-gate while (*str) {
70*7c478bd9Sstevel@tonic-gate area[--i] = *str++;
71*7c478bd9Sstevel@tonic-gate }
72*7c478bd9Sstevel@tonic-gate area[j] = '\0';
73*7c478bd9Sstevel@tonic-gate return (area);
74*7c478bd9Sstevel@tonic-gate }
75*7c478bd9Sstevel@tonic-gate
76*7c478bd9Sstevel@tonic-gate char *
Uppercase(register char * str)77*7c478bd9Sstevel@tonic-gate Uppercase(register char *str) /* return a pointer to an uppercase */
78*7c478bd9Sstevel@tonic-gate {
79*7c478bd9Sstevel@tonic-gate register char *ptr;
80*7c478bd9Sstevel@tonic-gate static char area[PATH_MAX];
81*7c478bd9Sstevel@tonic-gate
82*7c478bd9Sstevel@tonic-gate ptr = area;
83*7c478bd9Sstevel@tonic-gate while (*str) {
84*7c478bd9Sstevel@tonic-gate *(ptr++) = CRACK_TOUPPER(*str);
85*7c478bd9Sstevel@tonic-gate str++;
86*7c478bd9Sstevel@tonic-gate }
87*7c478bd9Sstevel@tonic-gate *ptr = '\0';
88*7c478bd9Sstevel@tonic-gate
89*7c478bd9Sstevel@tonic-gate return (area);
90*7c478bd9Sstevel@tonic-gate }
91*7c478bd9Sstevel@tonic-gate
92*7c478bd9Sstevel@tonic-gate char *
Lowercase(register char * str)93*7c478bd9Sstevel@tonic-gate Lowercase(register char *str) /* return a pointer to an lowercase */
94*7c478bd9Sstevel@tonic-gate {
95*7c478bd9Sstevel@tonic-gate register char *ptr;
96*7c478bd9Sstevel@tonic-gate static char area[PATH_MAX];
97*7c478bd9Sstevel@tonic-gate
98*7c478bd9Sstevel@tonic-gate ptr = area;
99*7c478bd9Sstevel@tonic-gate while (*str) {
100*7c478bd9Sstevel@tonic-gate *(ptr++) = CRACK_TOLOWER(*str);
101*7c478bd9Sstevel@tonic-gate str++;
102*7c478bd9Sstevel@tonic-gate }
103*7c478bd9Sstevel@tonic-gate *ptr = '\0';
104*7c478bd9Sstevel@tonic-gate
105*7c478bd9Sstevel@tonic-gate return (area);
106*7c478bd9Sstevel@tonic-gate }
107*7c478bd9Sstevel@tonic-gate
108*7c478bd9Sstevel@tonic-gate char *
Capitalise(register char * str)109*7c478bd9Sstevel@tonic-gate Capitalise(register char *str) /* return a pointer to an capitalised */
110*7c478bd9Sstevel@tonic-gate {
111*7c478bd9Sstevel@tonic-gate register char *ptr;
112*7c478bd9Sstevel@tonic-gate static char area[PATH_MAX];
113*7c478bd9Sstevel@tonic-gate
114*7c478bd9Sstevel@tonic-gate ptr = area;
115*7c478bd9Sstevel@tonic-gate
116*7c478bd9Sstevel@tonic-gate while (*str) {
117*7c478bd9Sstevel@tonic-gate *(ptr++) = CRACK_TOLOWER(*str);
118*7c478bd9Sstevel@tonic-gate str++;
119*7c478bd9Sstevel@tonic-gate }
120*7c478bd9Sstevel@tonic-gate
121*7c478bd9Sstevel@tonic-gate *ptr = '\0';
122*7c478bd9Sstevel@tonic-gate area[0] = CRACK_TOUPPER(area[0]);
123*7c478bd9Sstevel@tonic-gate return (area);
124*7c478bd9Sstevel@tonic-gate }
125*7c478bd9Sstevel@tonic-gate
126*7c478bd9Sstevel@tonic-gate char *
Pluralise(register char * string)127*7c478bd9Sstevel@tonic-gate Pluralise(register char *string) /* returns a pointer to a plural */
128*7c478bd9Sstevel@tonic-gate {
129*7c478bd9Sstevel@tonic-gate register int length;
130*7c478bd9Sstevel@tonic-gate static char area[PATH_MAX];
131*7c478bd9Sstevel@tonic-gate
132*7c478bd9Sstevel@tonic-gate length = strlen(string);
133*7c478bd9Sstevel@tonic-gate (void) strlcpy(area, string, PATH_MAX);
134*7c478bd9Sstevel@tonic-gate
135*7c478bd9Sstevel@tonic-gate if (!Suffix(string, "ch") ||
136*7c478bd9Sstevel@tonic-gate !Suffix(string, "ex") ||
137*7c478bd9Sstevel@tonic-gate !Suffix(string, "ix") ||
138*7c478bd9Sstevel@tonic-gate !Suffix(string, "sh") ||
139*7c478bd9Sstevel@tonic-gate !Suffix(string, "ss")) {
140*7c478bd9Sstevel@tonic-gate /* bench -> benches */
141*7c478bd9Sstevel@tonic-gate (void) strcat(area, "es");
142*7c478bd9Sstevel@tonic-gate } else if (length > 2 && string[length - 1] == 'y') {
143*7c478bd9Sstevel@tonic-gate if (strchr("aeiou", string[length - 2])) {
144*7c478bd9Sstevel@tonic-gate /* alloy -> alloys */
145*7c478bd9Sstevel@tonic-gate (void) strcat(area, "s");
146*7c478bd9Sstevel@tonic-gate } else {
147*7c478bd9Sstevel@tonic-gate /* gully -> gullies */
148*7c478bd9Sstevel@tonic-gate (void) strcpy(area + length - 1, "ies");
149*7c478bd9Sstevel@tonic-gate }
150*7c478bd9Sstevel@tonic-gate } else if (string[length - 1] == 's') {
151*7c478bd9Sstevel@tonic-gate /* bias -> biases */
152*7c478bd9Sstevel@tonic-gate (void) strcat(area, "es");
153*7c478bd9Sstevel@tonic-gate } else {
154*7c478bd9Sstevel@tonic-gate /* catchall */
155*7c478bd9Sstevel@tonic-gate (void) strcat(area, "s");
156*7c478bd9Sstevel@tonic-gate }
157*7c478bd9Sstevel@tonic-gate
158*7c478bd9Sstevel@tonic-gate return (area);
159*7c478bd9Sstevel@tonic-gate }
160*7c478bd9Sstevel@tonic-gate
161*7c478bd9Sstevel@tonic-gate char *
Substitute(register char * string,register char old,register char new)162*7c478bd9Sstevel@tonic-gate Substitute(register char *string, register char old,
163*7c478bd9Sstevel@tonic-gate register char new) /* returns pointer to a swapped about copy */
164*7c478bd9Sstevel@tonic-gate {
165*7c478bd9Sstevel@tonic-gate register char *ptr;
166*7c478bd9Sstevel@tonic-gate static char area[PATH_MAX];
167*7c478bd9Sstevel@tonic-gate
168*7c478bd9Sstevel@tonic-gate ptr = area;
169*7c478bd9Sstevel@tonic-gate while (*string) {
170*7c478bd9Sstevel@tonic-gate *(ptr++) = (*string == old ? new : *string);
171*7c478bd9Sstevel@tonic-gate string++;
172*7c478bd9Sstevel@tonic-gate }
173*7c478bd9Sstevel@tonic-gate *ptr = '\0';
174*7c478bd9Sstevel@tonic-gate return (area);
175*7c478bd9Sstevel@tonic-gate }
176*7c478bd9Sstevel@tonic-gate
177*7c478bd9Sstevel@tonic-gate /* returns pointer to a purged copy */
178*7c478bd9Sstevel@tonic-gate char *
Purge(register char * string,register char target)179*7c478bd9Sstevel@tonic-gate Purge(register char *string, register char target)
180*7c478bd9Sstevel@tonic-gate {
181*7c478bd9Sstevel@tonic-gate register char *ptr;
182*7c478bd9Sstevel@tonic-gate static char area[PATH_MAX];
183*7c478bd9Sstevel@tonic-gate ptr = area;
184*7c478bd9Sstevel@tonic-gate while (*string) {
185*7c478bd9Sstevel@tonic-gate if (*string != target) {
186*7c478bd9Sstevel@tonic-gate *(ptr++) = *string;
187*7c478bd9Sstevel@tonic-gate }
188*7c478bd9Sstevel@tonic-gate string++;
189*7c478bd9Sstevel@tonic-gate }
190*7c478bd9Sstevel@tonic-gate *ptr = '\0';
191*7c478bd9Sstevel@tonic-gate return (area);
192*7c478bd9Sstevel@tonic-gate }
193*7c478bd9Sstevel@tonic-gate /* -------- CHARACTER CLASSES START HERE -------- */
194*7c478bd9Sstevel@tonic-gate
195*7c478bd9Sstevel@tonic-gate /*
196*7c478bd9Sstevel@tonic-gate * this function takes two inputs, a class identifier and a character, and
197*7c478bd9Sstevel@tonic-gate * returns non-null if the given character is a member of the class, based
198*7c478bd9Sstevel@tonic-gate * upon restrictions set out below
199*7c478bd9Sstevel@tonic-gate */
200*7c478bd9Sstevel@tonic-gate
201*7c478bd9Sstevel@tonic-gate int
MatchClass(register char class,register char input)202*7c478bd9Sstevel@tonic-gate MatchClass(register char class, register char input)
203*7c478bd9Sstevel@tonic-gate {
204*7c478bd9Sstevel@tonic-gate register char c;
205*7c478bd9Sstevel@tonic-gate register int retval;
206*7c478bd9Sstevel@tonic-gate
207*7c478bd9Sstevel@tonic-gate retval = 0;
208*7c478bd9Sstevel@tonic-gate
209*7c478bd9Sstevel@tonic-gate switch (class) {
210*7c478bd9Sstevel@tonic-gate /* ESCAPE */
211*7c478bd9Sstevel@tonic-gate
212*7c478bd9Sstevel@tonic-gate case '?': /* ?? -> ? */
213*7c478bd9Sstevel@tonic-gate if (input == '?') {
214*7c478bd9Sstevel@tonic-gate retval = 1;
215*7c478bd9Sstevel@tonic-gate }
216*7c478bd9Sstevel@tonic-gate break;
217*7c478bd9Sstevel@tonic-gate
218*7c478bd9Sstevel@tonic-gate /* ILLOGICAL GROUPINGS (ie: not in ctype.h) */
219*7c478bd9Sstevel@tonic-gate
220*7c478bd9Sstevel@tonic-gate case 'V':
221*7c478bd9Sstevel@tonic-gate case 'v': /* vowels */
222*7c478bd9Sstevel@tonic-gate c = CRACK_TOLOWER(input);
223*7c478bd9Sstevel@tonic-gate if (strchr("aeiou", c)) {
224*7c478bd9Sstevel@tonic-gate retval = 1;
225*7c478bd9Sstevel@tonic-gate }
226*7c478bd9Sstevel@tonic-gate break;
227*7c478bd9Sstevel@tonic-gate
228*7c478bd9Sstevel@tonic-gate case 'C':
229*7c478bd9Sstevel@tonic-gate case 'c': /* consonants */
230*7c478bd9Sstevel@tonic-gate c = CRACK_TOLOWER(input);
231*7c478bd9Sstevel@tonic-gate if (strchr("bcdfghjklmnpqrstvwxyz", c)) {
232*7c478bd9Sstevel@tonic-gate retval = 1;
233*7c478bd9Sstevel@tonic-gate }
234*7c478bd9Sstevel@tonic-gate break;
235*7c478bd9Sstevel@tonic-gate
236*7c478bd9Sstevel@tonic-gate case 'W':
237*7c478bd9Sstevel@tonic-gate case 'w': /* whitespace */
238*7c478bd9Sstevel@tonic-gate if (strchr("\t ", input)) {
239*7c478bd9Sstevel@tonic-gate retval = 1;
240*7c478bd9Sstevel@tonic-gate }
241*7c478bd9Sstevel@tonic-gate break;
242*7c478bd9Sstevel@tonic-gate
243*7c478bd9Sstevel@tonic-gate case 'P':
244*7c478bd9Sstevel@tonic-gate case 'p': /* punctuation */
245*7c478bd9Sstevel@tonic-gate if (strchr(".`,:;'!?\"", input)) {
246*7c478bd9Sstevel@tonic-gate retval = 1;
247*7c478bd9Sstevel@tonic-gate }
248*7c478bd9Sstevel@tonic-gate break;
249*7c478bd9Sstevel@tonic-gate
250*7c478bd9Sstevel@tonic-gate case 'S':
251*7c478bd9Sstevel@tonic-gate case 's': /* symbols */
252*7c478bd9Sstevel@tonic-gate if (strchr("$%%^&*()-_+=|\\[]{}#@/~", input)) {
253*7c478bd9Sstevel@tonic-gate retval = 1;
254*7c478bd9Sstevel@tonic-gate }
255*7c478bd9Sstevel@tonic-gate break;
256*7c478bd9Sstevel@tonic-gate
257*7c478bd9Sstevel@tonic-gate /* LOGICAL GROUPINGS */
258*7c478bd9Sstevel@tonic-gate
259*7c478bd9Sstevel@tonic-gate case 'L':
260*7c478bd9Sstevel@tonic-gate case 'l': /* lowercase */
261*7c478bd9Sstevel@tonic-gate if (islower(input)) {
262*7c478bd9Sstevel@tonic-gate retval = 1;
263*7c478bd9Sstevel@tonic-gate }
264*7c478bd9Sstevel@tonic-gate break;
265*7c478bd9Sstevel@tonic-gate
266*7c478bd9Sstevel@tonic-gate case 'U':
267*7c478bd9Sstevel@tonic-gate case 'u': /* uppercase */
268*7c478bd9Sstevel@tonic-gate if (isupper(input)) {
269*7c478bd9Sstevel@tonic-gate retval = 1;
270*7c478bd9Sstevel@tonic-gate }
271*7c478bd9Sstevel@tonic-gate break;
272*7c478bd9Sstevel@tonic-gate
273*7c478bd9Sstevel@tonic-gate case 'A':
274*7c478bd9Sstevel@tonic-gate case 'a': /* alphabetic */
275*7c478bd9Sstevel@tonic-gate if (isalpha(input)) {
276*7c478bd9Sstevel@tonic-gate retval = 1;
277*7c478bd9Sstevel@tonic-gate }
278*7c478bd9Sstevel@tonic-gate break;
279*7c478bd9Sstevel@tonic-gate
280*7c478bd9Sstevel@tonic-gate case 'X':
281*7c478bd9Sstevel@tonic-gate case 'x': /* alphanumeric */
282*7c478bd9Sstevel@tonic-gate if (isalnum(input)) {
283*7c478bd9Sstevel@tonic-gate retval = 1;
284*7c478bd9Sstevel@tonic-gate }
285*7c478bd9Sstevel@tonic-gate break;
286*7c478bd9Sstevel@tonic-gate
287*7c478bd9Sstevel@tonic-gate case 'D':
288*7c478bd9Sstevel@tonic-gate case 'd': /* digits */
289*7c478bd9Sstevel@tonic-gate if (isdigit(input)) {
290*7c478bd9Sstevel@tonic-gate retval = 1;
291*7c478bd9Sstevel@tonic-gate }
292*7c478bd9Sstevel@tonic-gate break;
293*7c478bd9Sstevel@tonic-gate }
294*7c478bd9Sstevel@tonic-gate
295*7c478bd9Sstevel@tonic-gate if (isupper(class)) {
296*7c478bd9Sstevel@tonic-gate return (!retval);
297*7c478bd9Sstevel@tonic-gate }
298*7c478bd9Sstevel@tonic-gate return (retval);
299*7c478bd9Sstevel@tonic-gate }
300*7c478bd9Sstevel@tonic-gate
301*7c478bd9Sstevel@tonic-gate char *
PolyStrchr(register char * string,register char class)302*7c478bd9Sstevel@tonic-gate PolyStrchr(register char *string, register char class)
303*7c478bd9Sstevel@tonic-gate {
304*7c478bd9Sstevel@tonic-gate while (*string) {
305*7c478bd9Sstevel@tonic-gate if (MatchClass(class, *string)) {
306*7c478bd9Sstevel@tonic-gate return (string);
307*7c478bd9Sstevel@tonic-gate }
308*7c478bd9Sstevel@tonic-gate string++;
309*7c478bd9Sstevel@tonic-gate }
310*7c478bd9Sstevel@tonic-gate return ((char *)0);
311*7c478bd9Sstevel@tonic-gate }
312*7c478bd9Sstevel@tonic-gate
313*7c478bd9Sstevel@tonic-gate /* returns pointer to a swapped about copy */
314*7c478bd9Sstevel@tonic-gate char *
PolySubst(register char * string,register char class,register char new)315*7c478bd9Sstevel@tonic-gate PolySubst(register char *string, register char class, register char new)
316*7c478bd9Sstevel@tonic-gate {
317*7c478bd9Sstevel@tonic-gate register char *ptr;
318*7c478bd9Sstevel@tonic-gate static char area[PATH_MAX];
319*7c478bd9Sstevel@tonic-gate
320*7c478bd9Sstevel@tonic-gate ptr = area;
321*7c478bd9Sstevel@tonic-gate while (*string) {
322*7c478bd9Sstevel@tonic-gate *(ptr++) = (MatchClass(class, *string) ? new : *string);
323*7c478bd9Sstevel@tonic-gate string++;
324*7c478bd9Sstevel@tonic-gate }
325*7c478bd9Sstevel@tonic-gate *ptr = '\0';
326*7c478bd9Sstevel@tonic-gate return (area);
327*7c478bd9Sstevel@tonic-gate }
328*7c478bd9Sstevel@tonic-gate
329*7c478bd9Sstevel@tonic-gate /* returns pointer to a purged copy */
330*7c478bd9Sstevel@tonic-gate char *
PolyPurge(register char * string,register char class)331*7c478bd9Sstevel@tonic-gate PolyPurge(register char *string, register char class)
332*7c478bd9Sstevel@tonic-gate {
333*7c478bd9Sstevel@tonic-gate register char *ptr;
334*7c478bd9Sstevel@tonic-gate static char area[PATH_MAX];
335*7c478bd9Sstevel@tonic-gate
336*7c478bd9Sstevel@tonic-gate ptr = area;
337*7c478bd9Sstevel@tonic-gate while (*string) {
338*7c478bd9Sstevel@tonic-gate if (!MatchClass(class, *string)) {
339*7c478bd9Sstevel@tonic-gate *(ptr++) = *string;
340*7c478bd9Sstevel@tonic-gate }
341*7c478bd9Sstevel@tonic-gate string++;
342*7c478bd9Sstevel@tonic-gate }
343*7c478bd9Sstevel@tonic-gate *ptr = '\0';
344*7c478bd9Sstevel@tonic-gate return (area);
345*7c478bd9Sstevel@tonic-gate }
346*7c478bd9Sstevel@tonic-gate /* -------- BACK TO NORMALITY -------- */
347*7c478bd9Sstevel@tonic-gate
348*7c478bd9Sstevel@tonic-gate int
Char2Int(char character)349*7c478bd9Sstevel@tonic-gate Char2Int(char character)
350*7c478bd9Sstevel@tonic-gate {
351*7c478bd9Sstevel@tonic-gate if (isdigit(character)) {
352*7c478bd9Sstevel@tonic-gate return (character - '0');
353*7c478bd9Sstevel@tonic-gate } else if (islower(character)) {
354*7c478bd9Sstevel@tonic-gate return (character - 'a' + 10);
355*7c478bd9Sstevel@tonic-gate } else if (isupper(character)) {
356*7c478bd9Sstevel@tonic-gate return (character - 'A' + 10);
357*7c478bd9Sstevel@tonic-gate }
358*7c478bd9Sstevel@tonic-gate return (-1);
359*7c478bd9Sstevel@tonic-gate }
360*7c478bd9Sstevel@tonic-gate
361*7c478bd9Sstevel@tonic-gate /* returns a pointer to a controlled Mangle */
362*7c478bd9Sstevel@tonic-gate char *
Mangle(char * input,char * control)363*7c478bd9Sstevel@tonic-gate Mangle(char *input, char *control)
364*7c478bd9Sstevel@tonic-gate {
365*7c478bd9Sstevel@tonic-gate int limit;
366*7c478bd9Sstevel@tonic-gate register char *ptr;
367*7c478bd9Sstevel@tonic-gate static char area[PATH_MAX];
368*7c478bd9Sstevel@tonic-gate char area2[PATH_MAX];
369*7c478bd9Sstevel@tonic-gate
370*7c478bd9Sstevel@tonic-gate area[0] = '\0';
371*7c478bd9Sstevel@tonic-gate (void) strlcpy(area, input, PATH_MAX);
372*7c478bd9Sstevel@tonic-gate
373*7c478bd9Sstevel@tonic-gate for (ptr = control; *ptr; ptr++) {
374*7c478bd9Sstevel@tonic-gate switch (*ptr) {
375*7c478bd9Sstevel@tonic-gate case RULE_NOOP:
376*7c478bd9Sstevel@tonic-gate break;
377*7c478bd9Sstevel@tonic-gate case RULE_REVERSE:
378*7c478bd9Sstevel@tonic-gate (void) strlcpy(area, Reverse(area), PATH_MAX);
379*7c478bd9Sstevel@tonic-gate break;
380*7c478bd9Sstevel@tonic-gate case RULE_UPPERCASE:
381*7c478bd9Sstevel@tonic-gate (void) strlcpy(area, Uppercase(area), PATH_MAX);
382*7c478bd9Sstevel@tonic-gate break;
383*7c478bd9Sstevel@tonic-gate case RULE_LOWERCASE:
384*7c478bd9Sstevel@tonic-gate (void) strlcpy(area, Lowercase(area), PATH_MAX);
385*7c478bd9Sstevel@tonic-gate break;
386*7c478bd9Sstevel@tonic-gate case RULE_CAPITALISE:
387*7c478bd9Sstevel@tonic-gate (void) strlcpy(area, Capitalise(area),
388*7c478bd9Sstevel@tonic-gate PATH_MAX);
389*7c478bd9Sstevel@tonic-gate break;
390*7c478bd9Sstevel@tonic-gate case RULE_PLURALISE:
391*7c478bd9Sstevel@tonic-gate (void) strlcpy(area, Pluralise(area), PATH_MAX);
392*7c478bd9Sstevel@tonic-gate break;
393*7c478bd9Sstevel@tonic-gate case RULE_REFLECT:
394*7c478bd9Sstevel@tonic-gate (void) strlcat(area, Reverse(area), PATH_MAX);
395*7c478bd9Sstevel@tonic-gate break;
396*7c478bd9Sstevel@tonic-gate case RULE_DUPLICATE:
397*7c478bd9Sstevel@tonic-gate (void) strlcpy(area2, area, PATH_MAX);
398*7c478bd9Sstevel@tonic-gate (void) strlcat(area, area2, PATH_MAX);
399*7c478bd9Sstevel@tonic-gate break;
400*7c478bd9Sstevel@tonic-gate case RULE_GT:
401*7c478bd9Sstevel@tonic-gate if (!ptr[1]) {
402*7c478bd9Sstevel@tonic-gate return ((char *)0);
403*7c478bd9Sstevel@tonic-gate } else {
404*7c478bd9Sstevel@tonic-gate limit = Char2Int(*(++ptr));
405*7c478bd9Sstevel@tonic-gate if (limit < 0) {
406*7c478bd9Sstevel@tonic-gate return ((char *)0);
407*7c478bd9Sstevel@tonic-gate }
408*7c478bd9Sstevel@tonic-gate if (strlen(area) <= limit) {
409*7c478bd9Sstevel@tonic-gate return ((char *)0);
410*7c478bd9Sstevel@tonic-gate }
411*7c478bd9Sstevel@tonic-gate }
412*7c478bd9Sstevel@tonic-gate break;
413*7c478bd9Sstevel@tonic-gate case RULE_LT:
414*7c478bd9Sstevel@tonic-gate if (!ptr[1]) {
415*7c478bd9Sstevel@tonic-gate return ((char *)0);
416*7c478bd9Sstevel@tonic-gate } else {
417*7c478bd9Sstevel@tonic-gate limit = Char2Int(*(++ptr));
418*7c478bd9Sstevel@tonic-gate if (limit < 0) {
419*7c478bd9Sstevel@tonic-gate return ((char *)0);
420*7c478bd9Sstevel@tonic-gate }
421*7c478bd9Sstevel@tonic-gate if (strlen(area) >= limit) {
422*7c478bd9Sstevel@tonic-gate return ((char *)0);
423*7c478bd9Sstevel@tonic-gate }
424*7c478bd9Sstevel@tonic-gate }
425*7c478bd9Sstevel@tonic-gate break;
426*7c478bd9Sstevel@tonic-gate case RULE_PREPEND:
427*7c478bd9Sstevel@tonic-gate if (!ptr[1]) {
428*7c478bd9Sstevel@tonic-gate return ((char *)0);
429*7c478bd9Sstevel@tonic-gate } else {
430*7c478bd9Sstevel@tonic-gate area2[0] = *(++ptr);
431*7c478bd9Sstevel@tonic-gate (void) strlcpy(area2 + 1, area,
432*7c478bd9Sstevel@tonic-gate PATH_MAX);
433*7c478bd9Sstevel@tonic-gate (void) strlcpy(area, area2, PATH_MAX);
434*7c478bd9Sstevel@tonic-gate }
435*7c478bd9Sstevel@tonic-gate break;
436*7c478bd9Sstevel@tonic-gate case RULE_APPEND:
437*7c478bd9Sstevel@tonic-gate if (!ptr[1]) {
438*7c478bd9Sstevel@tonic-gate return ((char *)0);
439*7c478bd9Sstevel@tonic-gate } else {
440*7c478bd9Sstevel@tonic-gate register char *string;
441*7c478bd9Sstevel@tonic-gate
442*7c478bd9Sstevel@tonic-gate string = area;
443*7c478bd9Sstevel@tonic-gate while (*(string++));
444*7c478bd9Sstevel@tonic-gate string[-1] = *(++ptr);
445*7c478bd9Sstevel@tonic-gate *string = '\0';
446*7c478bd9Sstevel@tonic-gate }
447*7c478bd9Sstevel@tonic-gate break;
448*7c478bd9Sstevel@tonic-gate case RULE_EXTRACT:
449*7c478bd9Sstevel@tonic-gate if (!ptr[1] || !ptr[2]) {
450*7c478bd9Sstevel@tonic-gate return ((char *)0);
451*7c478bd9Sstevel@tonic-gate } else {
452*7c478bd9Sstevel@tonic-gate register int i;
453*7c478bd9Sstevel@tonic-gate int start;
454*7c478bd9Sstevel@tonic-gate int length;
455*7c478bd9Sstevel@tonic-gate
456*7c478bd9Sstevel@tonic-gate start = Char2Int(*(++ptr));
457*7c478bd9Sstevel@tonic-gate length = Char2Int(*(++ptr));
458*7c478bd9Sstevel@tonic-gate if (start < 0 || length < 0) {
459*7c478bd9Sstevel@tonic-gate return ((char *)0);
460*7c478bd9Sstevel@tonic-gate }
461*7c478bd9Sstevel@tonic-gate (void) strlcpy(area2, area, PATH_MAX);
462*7c478bd9Sstevel@tonic-gate for (i = 0; length-- &&
463*7c478bd9Sstevel@tonic-gate area2[start + i]; i++) {
464*7c478bd9Sstevel@tonic-gate area[i] = area2[start + i];
465*7c478bd9Sstevel@tonic-gate }
466*7c478bd9Sstevel@tonic-gate /* cant use strncpy()-no trailing NUL */
467*7c478bd9Sstevel@tonic-gate area[i] = '\0';
468*7c478bd9Sstevel@tonic-gate }
469*7c478bd9Sstevel@tonic-gate break;
470*7c478bd9Sstevel@tonic-gate case RULE_OVERSTRIKE:
471*7c478bd9Sstevel@tonic-gate if (!ptr[1] || !ptr[2]) {
472*7c478bd9Sstevel@tonic-gate return ((char *)0);
473*7c478bd9Sstevel@tonic-gate } else {
474*7c478bd9Sstevel@tonic-gate register int i;
475*7c478bd9Sstevel@tonic-gate
476*7c478bd9Sstevel@tonic-gate i = Char2Int(*(++ptr));
477*7c478bd9Sstevel@tonic-gate if (i < 0) {
478*7c478bd9Sstevel@tonic-gate return ((char *)0);
479*7c478bd9Sstevel@tonic-gate } else {
480*7c478bd9Sstevel@tonic-gate ++ptr;
481*7c478bd9Sstevel@tonic-gate if (area[i]) {
482*7c478bd9Sstevel@tonic-gate area[i] = *ptr;
483*7c478bd9Sstevel@tonic-gate }
484*7c478bd9Sstevel@tonic-gate }
485*7c478bd9Sstevel@tonic-gate }
486*7c478bd9Sstevel@tonic-gate break;
487*7c478bd9Sstevel@tonic-gate case RULE_INSERT:
488*7c478bd9Sstevel@tonic-gate if (!ptr[1] || !ptr[2]) {
489*7c478bd9Sstevel@tonic-gate return ((char *)0);
490*7c478bd9Sstevel@tonic-gate } else {
491*7c478bd9Sstevel@tonic-gate register int i;
492*7c478bd9Sstevel@tonic-gate register char *p1;
493*7c478bd9Sstevel@tonic-gate register char *p2;
494*7c478bd9Sstevel@tonic-gate
495*7c478bd9Sstevel@tonic-gate i = Char2Int(*(++ptr));
496*7c478bd9Sstevel@tonic-gate if (i < 0) {
497*7c478bd9Sstevel@tonic-gate return ((char *)0);
498*7c478bd9Sstevel@tonic-gate }
499*7c478bd9Sstevel@tonic-gate p1 = area;
500*7c478bd9Sstevel@tonic-gate p2 = area2;
501*7c478bd9Sstevel@tonic-gate while (i && *p1) {
502*7c478bd9Sstevel@tonic-gate i--;
503*7c478bd9Sstevel@tonic-gate *(p2++) = *(p1++);
504*7c478bd9Sstevel@tonic-gate }
505*7c478bd9Sstevel@tonic-gate *(p2++) = *(++ptr);
506*7c478bd9Sstevel@tonic-gate (void) strlcpy(p2, p1, PATH_MAX);
507*7c478bd9Sstevel@tonic-gate (void) strlcpy(area, area2, PATH_MAX);
508*7c478bd9Sstevel@tonic-gate }
509*7c478bd9Sstevel@tonic-gate break;
510*7c478bd9Sstevel@tonic-gate /* THE FOLLOWING RULES REQUIRE CLASS MATCHING */
511*7c478bd9Sstevel@tonic-gate
512*7c478bd9Sstevel@tonic-gate case RULE_PURGE: /* @x or @?c */
513*7c478bd9Sstevel@tonic-gate if (!ptr[1] || (ptr[1] ==
514*7c478bd9Sstevel@tonic-gate RULE_CLASS && !ptr[2])) {
515*7c478bd9Sstevel@tonic-gate return ((char *)0);
516*7c478bd9Sstevel@tonic-gate } else if (ptr[1] != RULE_CLASS) {
517*7c478bd9Sstevel@tonic-gate (void) strlcpy(area, Purge(area,
518*7c478bd9Sstevel@tonic-gate *(++ptr)), PATH_MAX);
519*7c478bd9Sstevel@tonic-gate } else {
520*7c478bd9Sstevel@tonic-gate (void) strlcpy(area, PolyPurge(area,
521*7c478bd9Sstevel@tonic-gate ptr[2]), PATH_MAX);
522*7c478bd9Sstevel@tonic-gate ptr += 2;
523*7c478bd9Sstevel@tonic-gate }
524*7c478bd9Sstevel@tonic-gate break;
525*7c478bd9Sstevel@tonic-gate case RULE_SUBSTITUTE: /* sxy || s?cy */
526*7c478bd9Sstevel@tonic-gate if (!ptr[1] || !ptr[2] ||
527*7c478bd9Sstevel@tonic-gate (ptr[1] == RULE_CLASS && !ptr[3])) {
528*7c478bd9Sstevel@tonic-gate return ((char *)0);
529*7c478bd9Sstevel@tonic-gate } else if (ptr[1] != RULE_CLASS) {
530*7c478bd9Sstevel@tonic-gate ptr += 2;
531*7c478bd9Sstevel@tonic-gate } else {
532*7c478bd9Sstevel@tonic-gate (void) strlcpy(area, PolySubst(area,
533*7c478bd9Sstevel@tonic-gate ptr[2], ptr[3]), PATH_MAX);
534*7c478bd9Sstevel@tonic-gate ptr += 3;
535*7c478bd9Sstevel@tonic-gate }
536*7c478bd9Sstevel@tonic-gate break;
537*7c478bd9Sstevel@tonic-gate case RULE_MATCH: /* /x || /?c */
538*7c478bd9Sstevel@tonic-gate if (!ptr[1] ||
539*7c478bd9Sstevel@tonic-gate (ptr[1] == RULE_CLASS && !ptr[2])) {
540*7c478bd9Sstevel@tonic-gate return ((char *)0);
541*7c478bd9Sstevel@tonic-gate } else if (ptr[1] != RULE_CLASS) {
542*7c478bd9Sstevel@tonic-gate if (!strchr(area, *(++ptr))) {
543*7c478bd9Sstevel@tonic-gate return ((char *)0);
544*7c478bd9Sstevel@tonic-gate }
545*7c478bd9Sstevel@tonic-gate } else {
546*7c478bd9Sstevel@tonic-gate if (!PolyStrchr(area, ptr[2])) {
547*7c478bd9Sstevel@tonic-gate return ((char *)0);
548*7c478bd9Sstevel@tonic-gate }
549*7c478bd9Sstevel@tonic-gate ptr += 2;
550*7c478bd9Sstevel@tonic-gate }
551*7c478bd9Sstevel@tonic-gate break;
552*7c478bd9Sstevel@tonic-gate case RULE_NOT: /* !x || !?c */
553*7c478bd9Sstevel@tonic-gate if (!ptr[1] ||
554*7c478bd9Sstevel@tonic-gate (ptr[1] == RULE_CLASS && !ptr[2])) {
555*7c478bd9Sstevel@tonic-gate return ((char *)0);
556*7c478bd9Sstevel@tonic-gate } else if (ptr[1] != RULE_CLASS) {
557*7c478bd9Sstevel@tonic-gate if (strchr(area, *(++ptr))) {
558*7c478bd9Sstevel@tonic-gate return ((char *)0);
559*7c478bd9Sstevel@tonic-gate }
560*7c478bd9Sstevel@tonic-gate } else {
561*7c478bd9Sstevel@tonic-gate if (PolyStrchr(area, ptr[2])) {
562*7c478bd9Sstevel@tonic-gate return ((char *)0);
563*7c478bd9Sstevel@tonic-gate }
564*7c478bd9Sstevel@tonic-gate ptr += 2;
565*7c478bd9Sstevel@tonic-gate }
566*7c478bd9Sstevel@tonic-gate break;
567*7c478bd9Sstevel@tonic-gate /*
568*7c478bd9Sstevel@tonic-gate * alternative use for a boomerang, number 1: a standard throwing
569*7c478bd9Sstevel@tonic-gate * boomerang is an ideal thing to use to tuck the sheets under
570*7c478bd9Sstevel@tonic-gate * the mattress when making your bed. The streamlined shape of
571*7c478bd9Sstevel@tonic-gate * the boomerang allows it to slip easily 'twixt mattress and
572*7c478bd9Sstevel@tonic-gate * bedframe, and it's curve makes it very easy to hook sheets
573*7c478bd9Sstevel@tonic-gate * into the gap.
574*7c478bd9Sstevel@tonic-gate */
575*7c478bd9Sstevel@tonic-gate
576*7c478bd9Sstevel@tonic-gate case RULE_EQUALS: /* =nx || =n?c */
577*7c478bd9Sstevel@tonic-gate if (!ptr[1] || !ptr[2] ||
578*7c478bd9Sstevel@tonic-gate (ptr[2] == RULE_CLASS && !ptr[3])) {
579*7c478bd9Sstevel@tonic-gate return ((char *)0);
580*7c478bd9Sstevel@tonic-gate } else {
581*7c478bd9Sstevel@tonic-gate register int i;
582*7c478bd9Sstevel@tonic-gate
583*7c478bd9Sstevel@tonic-gate if ((i = Char2Int(ptr[1])) < 0) {
584*7c478bd9Sstevel@tonic-gate return ((char *)0);
585*7c478bd9Sstevel@tonic-gate }
586*7c478bd9Sstevel@tonic-gate if (ptr[2] != RULE_CLASS) {
587*7c478bd9Sstevel@tonic-gate ptr += 2;
588*7c478bd9Sstevel@tonic-gate if (area[i] != *ptr) {
589*7c478bd9Sstevel@tonic-gate return ((char *)0);
590*7c478bd9Sstevel@tonic-gate }
591*7c478bd9Sstevel@tonic-gate } else {
592*7c478bd9Sstevel@tonic-gate ptr += 3;
593*7c478bd9Sstevel@tonic-gate if (!MatchClass(*ptr,
594*7c478bd9Sstevel@tonic-gate area[i])) {
595*7c478bd9Sstevel@tonic-gate return ((char *)0);
596*7c478bd9Sstevel@tonic-gate }
597*7c478bd9Sstevel@tonic-gate }
598*7c478bd9Sstevel@tonic-gate }
599*7c478bd9Sstevel@tonic-gate break;
600*7c478bd9Sstevel@tonic-gate
601*7c478bd9Sstevel@tonic-gate case RULE_DFIRST:
602*7c478bd9Sstevel@tonic-gate if (area[0]) {
603*7c478bd9Sstevel@tonic-gate register int i;
604*7c478bd9Sstevel@tonic-gate
605*7c478bd9Sstevel@tonic-gate for (i = 1; area[i]; i++) {
606*7c478bd9Sstevel@tonic-gate area[i - 1] = area[i];
607*7c478bd9Sstevel@tonic-gate }
608*7c478bd9Sstevel@tonic-gate area[i - 1] = '\0';
609*7c478bd9Sstevel@tonic-gate }
610*7c478bd9Sstevel@tonic-gate break;
611*7c478bd9Sstevel@tonic-gate
612*7c478bd9Sstevel@tonic-gate case RULE_DLAST:
613*7c478bd9Sstevel@tonic-gate if (area[0]) {
614*7c478bd9Sstevel@tonic-gate register int i;
615*7c478bd9Sstevel@tonic-gate
616*7c478bd9Sstevel@tonic-gate for (i = 1; area[i]; i++);
617*7c478bd9Sstevel@tonic-gate area[i - 1] = '\0';
618*7c478bd9Sstevel@tonic-gate }
619*7c478bd9Sstevel@tonic-gate break;
620*7c478bd9Sstevel@tonic-gate
621*7c478bd9Sstevel@tonic-gate case RULE_MFIRST:
622*7c478bd9Sstevel@tonic-gate if (!ptr[1] ||
623*7c478bd9Sstevel@tonic-gate (ptr[1] == RULE_CLASS && !ptr[2])) {
624*7c478bd9Sstevel@tonic-gate return ((char *)0);
625*7c478bd9Sstevel@tonic-gate } else {
626*7c478bd9Sstevel@tonic-gate if (ptr[1] != RULE_CLASS) {
627*7c478bd9Sstevel@tonic-gate ptr++;
628*7c478bd9Sstevel@tonic-gate if (area[0] != *ptr) {
629*7c478bd9Sstevel@tonic-gate return ((char *)0);
630*7c478bd9Sstevel@tonic-gate }
631*7c478bd9Sstevel@tonic-gate } else {
632*7c478bd9Sstevel@tonic-gate ptr += 2;
633*7c478bd9Sstevel@tonic-gate if (!MatchClass(*ptr,
634*7c478bd9Sstevel@tonic-gate area[0])) {
635*7c478bd9Sstevel@tonic-gate return ((char *)0);
636*7c478bd9Sstevel@tonic-gate }
637*7c478bd9Sstevel@tonic-gate }
638*7c478bd9Sstevel@tonic-gate }
639*7c478bd9Sstevel@tonic-gate break;
640*7c478bd9Sstevel@tonic-gate case RULE_MLAST:
641*7c478bd9Sstevel@tonic-gate if (!ptr[1] ||
642*7c478bd9Sstevel@tonic-gate (ptr[1] == RULE_CLASS && !ptr[2])) {
643*7c478bd9Sstevel@tonic-gate return ((char *)0);
644*7c478bd9Sstevel@tonic-gate } else {
645*7c478bd9Sstevel@tonic-gate register int i;
646*7c478bd9Sstevel@tonic-gate
647*7c478bd9Sstevel@tonic-gate for (i = 0; area[i]; i++);
648*7c478bd9Sstevel@tonic-gate
649*7c478bd9Sstevel@tonic-gate if (i > 0) {
650*7c478bd9Sstevel@tonic-gate i--;
651*7c478bd9Sstevel@tonic-gate } else {
652*7c478bd9Sstevel@tonic-gate return ((char *)0);
653*7c478bd9Sstevel@tonic-gate }
654*7c478bd9Sstevel@tonic-gate if (ptr[1] != RULE_CLASS) {
655*7c478bd9Sstevel@tonic-gate ptr++;
656*7c478bd9Sstevel@tonic-gate if (area[i] != *ptr) {
657*7c478bd9Sstevel@tonic-gate return ((char *)0);
658*7c478bd9Sstevel@tonic-gate }
659*7c478bd9Sstevel@tonic-gate } else {
660*7c478bd9Sstevel@tonic-gate ptr += 2;
661*7c478bd9Sstevel@tonic-gate if (!MatchClass(*ptr,
662*7c478bd9Sstevel@tonic-gate area[i])) {
663*7c478bd9Sstevel@tonic-gate return ((char *)0);
664*7c478bd9Sstevel@tonic-gate }
665*7c478bd9Sstevel@tonic-gate }
666*7c478bd9Sstevel@tonic-gate }
667*7c478bd9Sstevel@tonic-gate break;
668*7c478bd9Sstevel@tonic-gate }
669*7c478bd9Sstevel@tonic-gate }
670*7c478bd9Sstevel@tonic-gate if (!area[0]) { /* have we deweted de poor widdle fing away? */
671*7c478bd9Sstevel@tonic-gate return ((char *)0);
672*7c478bd9Sstevel@tonic-gate }
673*7c478bd9Sstevel@tonic-gate return (area);
674*7c478bd9Sstevel@tonic-gate }
675*7c478bd9Sstevel@tonic-gate /*
676*7c478bd9Sstevel@tonic-gate * int
677*7c478bd9Sstevel@tonic-gate * PMatch(register char *control, register char *string)
678*7c478bd9Sstevel@tonic-gate * {
679*7c478bd9Sstevel@tonic-gate * while (*string && *control) {
680*7c478bd9Sstevel@tonic-gate * if (!MatchClass(*control, *string)) {
681*7c478bd9Sstevel@tonic-gate * return (0);
682*7c478bd9Sstevel@tonic-gate * }
683*7c478bd9Sstevel@tonic-gate *
684*7c478bd9Sstevel@tonic-gate * string++;
685*7c478bd9Sstevel@tonic-gate * control++;
686*7c478bd9Sstevel@tonic-gate * }
687*7c478bd9Sstevel@tonic-gate *
688*7c478bd9Sstevel@tonic-gate * if (*string || *control) {
689*7c478bd9Sstevel@tonic-gate * return (0);
690*7c478bd9Sstevel@tonic-gate * }
691*7c478bd9Sstevel@tonic-gate *
692*7c478bd9Sstevel@tonic-gate * return (1);
693*7c478bd9Sstevel@tonic-gate * }
694*7c478bd9Sstevel@tonic-gate */
695