xfstests updates - rework build to be like other xfs packages, revive some old fs...
[xfstests-dev.git] / lib / databin.c
1 /*
2  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
3  * 
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  * 
8  * This program is distributed in the hope that it would be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  * 
12  * Further, this software is distributed without any warranty that it is
13  * free of the rightful claim of any third person regarding infringement
14  * or the like.  Any license provided herein, whether implied or
15  * otherwise, applies only to this software file.  Patent licenses, if
16  * any, provided herein do not apply to combinations of this program with
17  * other software, or any other product whatsoever.
18  * 
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write the Free Software Foundation, Inc., 59
21  * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22  * 
23  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24  * Mountain View, CA  94043, or:
25  * 
26  * http://www.sgi.com 
27  * 
28  * For further information regarding this notice, see: 
29  * 
30  * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
31  */
32 #include <stdio.h>
33 #include <sys/param.h>
34 #include <string.h> /* memset */
35 #include <stdlib.h> /* rand */
36 #include "databin.h"
37
38 #if UNIT_TEST
39 #include <malloc.h>
40 #endif
41
42 static char Errmsg[80];
43
44 void
45 databingen (mode, buffer, bsize, offset)
46 int mode;       /* either a, c, r, o, z or C */
47 unsigned char *buffer;  /* buffer pointer */
48 int bsize;      /* size of buffer */
49 int offset;     /* offset into the file where buffer starts */
50 {
51 int ind;
52
53         switch (mode)
54         {
55         default:
56         case 'a':       /* alternating bit pattern */
57                 memset(buffer,0x55,bsize);
58                 break;
59
60         case 'c':       /* checkerboard pattern */
61                 memset(buffer,0xf0,bsize);
62                 break;
63
64         case 'C':       /* */
65                 for (ind=0;ind< bsize;ind++) {
66                     buffer[ind] = ((offset+ind)%8 & 0177);
67                 }
68                 break;
69
70         case 'o':
71                 memset(buffer,0xff,bsize);
72                 break;
73
74         case 'z':
75                 memset(buffer,0x0,bsize);
76                 break;
77
78         case 'r':       /* random */
79                 for (ind=0;ind< bsize;ind++) {
80                     buffer[ind] = (rand () & 0177) | 0100;
81                 }
82         }
83 }
84
85 /***********************************************************************
86  *
87  * return values:
88  *      >= 0 : error at byte offset into the file, offset+buffer[0-(bsize-1)]
89  *      < 0  : no error
90  ***********************************************************************/
91 int
92 databinchk(mode, buffer, bsize, offset, errmsg)
93 int mode;       /* either a, c, r, z, o, or C */
94 unsigned char *buffer;  /* buffer pointer */
95 int bsize;      /* size of buffer */
96 int offset;     /* offset into the file where buffer starts */
97 char **errmsg;
98 {
99     int cnt;
100     unsigned char *chr;
101     int total;
102     long expbits;
103     long actbits;
104
105         chr=buffer;
106         total=bsize;
107
108         if ( errmsg != NULL ) {
109             *errmsg = Errmsg;
110         }
111         
112         switch (mode)
113         {
114         default:
115         case 'a':       /* alternating bit pattern */
116                 expbits=0x55;
117                 break;
118
119         case 'c':       /* checkerboard pattern */
120                 expbits=0xf0;
121                 break;
122
123         case 'C':       /* counting pattern */
124                 for (cnt=0;cnt< bsize;cnt++) {
125                     expbits = ((offset+cnt)%8 & 0177);
126
127                     if ( buffer[cnt] != expbits ) {
128                         sprintf(Errmsg,
129                             "data mismatch at offset %d, exp:%#lo, act:%#o",
130                             offset+cnt, expbits, buffer[cnt]);
131                         return offset+cnt;
132                     }
133                 }
134                 sprintf(Errmsg, "all %d bytes match desired pattern", bsize);
135                 return -1;
136
137         case 'o':
138                 expbits=0xff;
139                 break;
140
141         case 'z':
142                 expbits=0;
143                 break;
144
145         case 'r':
146                 return -1;      /* no check can be done for random */
147         }
148
149         for (cnt=0; cnt<bsize; chr++, cnt++) {
150             actbits = (long)*chr;
151
152             if ( actbits != expbits ) {
153                 sprintf(Errmsg, "data mismatch at offset %d, exp:%#lo, act:%#lo",
154                     offset+cnt, expbits, actbits);
155                 return offset+cnt;
156             }
157         }
158
159         sprintf(Errmsg, "all %d bytes match desired pattern", bsize);
160         return -1; /* all ok */
161 }
162
163 #if UNIT_TEST
164
165 /***********************************************************************
166  * main for doing unit testing
167  ***********************************************************************/
168 int
169 main(ac, ag)
170 int ac;
171 char **ag;
172 {
173
174     int size=1023;
175     int offset;
176     int number;
177     unsigned char *buffer;
178     int ret;
179     char *errmsg;
180
181     if ((buffer=(unsigned char *)malloc(size)) == NULL ) {
182         perror("malloc");
183         exit(2);
184     }
185
186
187 printf("***** for a ****************************\n");
188     databingen('a', buffer, size, 0);
189     printf("databingen('a', buffer, %d, 0)\n", size);
190
191     ret=databinchk('a', buffer, size, 0, &errmsg);
192     printf("databinchk('a', buffer, %d, 0, &errmsg) returned %d: %s\n",
193         size, ret, errmsg);
194     if ( ret == -1 )
195         printf("\tPASS return value of -1 as expected\n");
196     else
197         printf("\tFAIL return value %d, expected -1\n", ret);
198
199     offset=232400;
200     ret=databinchk('a', &buffer[1], size-1, offset, &errmsg);
201     printf("databinchk('a', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
202         size, offset, ret, errmsg);
203     if ( ret == -1 )
204         printf("\tPASS return value of -1 as expected\n");
205     else
206         printf("\tFAIL return value %d, expected -1\n", ret);
207
208     buffer[15]= 0x0;
209     printf("changing char 15 (offset (%d+15) = %d) to 0x0\n", offset, offset+15);
210     number=offset+15;
211
212     ret=databinchk('a', &buffer[1], size-1, offset+1, &errmsg);
213     printf("databinchk('a', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
214         size-1, offset+1, ret, errmsg);
215     if ( ret == number )
216         printf("\tPASS return value of %d as expected\n", number);
217     else
218         printf("\tFAIL return value %d, expected %d\n", ret, number);
219
220
221
222 printf("***** for c ****************************\n");
223     databingen('c', buffer, size, 0);
224     printf("databingen('c', buffer, %d, 0)\n", size);
225
226     ret=databinchk('c', buffer, size, 0, &errmsg);
227     printf("databinchk('c', buffer, %d, 0, &errmsg) returned %d: %s\n",
228         size, ret, errmsg);
229     if ( ret == -1 )
230         printf("\tPASS return value of -1 as expected\n");
231     else
232         printf("\tFAIL return value %d, expected -1\n", ret);
233
234     offset=232400;
235     ret=databinchk('c', &buffer[1], size-1, offset, &errmsg);
236     printf("databinchk('c', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
237         size, offset, ret, errmsg);
238     if ( ret == -1 )
239         printf("\tPASS return value of -1 as expected\n");
240     else
241         printf("\tFAIL return value %d, expected -1\n", ret);
242
243     buffer[15]= 0x0;
244     printf("changing char 15 (offset (%d+15) = %d) to 0x0\n", offset, offset+15);
245     number=offset+15;
246
247     ret=databinchk('c', &buffer[1], size-1, offset+1, &errmsg);
248     printf("databinchk('c', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
249         size-1, offset+1, ret, errmsg);
250     if ( ret == number )
251         printf("\tPASS return value of %d as expected\n", number);
252     else
253         printf("\tFAIL return value %d, expected %d\n", ret, number);
254
255 printf("***** for C ****************************\n");
256
257     databingen('C', buffer, size, 0);
258     printf("databingen('C', buffer, %d, 0)\n", size);
259
260     ret=databinchk('C', buffer, size, 0, &errmsg);
261     printf("databinchk('C', buffer, %d, 0, &errmsg) returned %d: %s\n",
262         size, ret, errmsg);
263     if ( ret == -1 )
264         printf("\tPASS return value of -1 as expected\n");
265     else
266         printf("\tFAIL return value %d, expected -1\n", ret);
267
268     offset=18;
269     ret=databinchk('C', &buffer[18], size-18, 18, &errmsg);
270     printf("databinchk('C', &buffer[18], %d, 18, &errmsg) returned %d: %s\n",
271         size-18, ret, errmsg);
272     if ( ret == -1 )
273         printf("\tPASS return value of -1 as expected\n");
274     else
275         printf("\tFAIL return value %d, expected -1\n", ret);
276
277     buffer[20]= 0x0;
278     buffer[21]= 0x0;
279     printf("changing char 20 and 21 to 0x0 (offset %d and %d)\n", 20,
280         21);
281
282     ret=databinchk('C', &buffer[18], size-18, 18, &errmsg);
283     printf("databinchk('C', &buffer[18], %d, 18, &errmsg) returned %d: %s\n",
284         size-18, ret, errmsg);
285
286     if ( ret == 20 || ret == 21 )
287         printf("\tPASS return value of %d or %d as expected\n",
288             20, 21);
289     else
290         printf("\tFAIL return value %d, expected %d or %d\n", ret,
291             20, 21 );
292
293     exit(0);
294
295 }
296
297 #endif
298