ChangeLog part of dist
[yaz-moved-to-github.git] / client / bertorture.c
1 /* 
2  * Copyright (C) 1995-2007, Index Data ApS
3  * See the file LICENSE for details.
4  *
5  * $Id: bertorture.c,v 1.5 2007-01-03 08:42:13 adam Exp $
6  */
7
8 #include <signal.h>
9 #if HAVE_SYS_TYPES_H
10 #include <sys/types.h>
11 #endif
12 #if HAVE_SYS_STAT_H
13 #include <sys/stat.h>
14 #endif
15 #include <fcntl.h>
16 #if HAVE_UNISTD_H
17 #include <unistd.h>
18 #endif
19
20 #include <stdlib.h>
21 #include <stdio.h>
22
23 #include <yaz/yaz-util.h>
24 #include <yaz/proto.h>
25 #include <yaz/comstack.h>
26
27 #define PACKET_SIZE 64
28
29 static int stop = 0;
30
31 static int send_packet(const char *host)
32 {
33     char buf[PACKET_SIZE];
34     int i;
35
36     void *add;
37
38     COMSTACK cs = cs_create_host(host, 1, &add);
39
40     if (!cs)
41         return -1;
42
43     if (cs_connect(cs, add) < 0)
44         return -1;
45
46     for (i = 0; i<sizeof(buf); i++)
47         buf[i] = 233;
48 #if 0
49         buf[i] = rand() & 0xff;
50 #endif
51     cs_put(cs, buf, sizeof(buf));
52
53     cs_close(cs);
54     return 0;
55 }
56
57 static void test_file(const char *fname)
58 {
59     Z_GDU *req;
60     ODR odr = odr_createmem(ODR_DECODE);
61     char buf[PACKET_SIZE];
62     int off = 0;
63     int fd =open(fname, O_RDONLY, 0666);
64     if (fd == -1)
65     {
66         yaz_log(LOG_ERRNO|LOG_FATAL, "open %s", fname);
67         exit (1);
68     }
69     while (off < sizeof(buf))
70     {
71         ssize_t rd;
72         rd = read(fd, buf+off, sizeof(buf)-off);
73         if (rd == -1) {
74             yaz_log(LOG_ERRNO|LOG_FATAL, "read %s", fname);
75             exit (1);
76         }
77         if (rd == 0)
78             break;
79         off += rd;
80     }
81     if (close(fd) == -1)
82     {
83         yaz_log(LOG_ERRNO|LOG_FATAL, "close %s", fname);
84         exit (1);
85     }
86     odr_setbuf(odr, buf, off, 0);
87     z_GDU(odr, &req, 0, 0);
88
89     odr_destroy(odr);
90 }
91
92 static void test_random(int run, const char *fname, const char *fname2,
93                         int *estat)
94 {
95     FILE *dumpfile = 0;
96     char buf[PACKET_SIZE];
97     int i, j;
98
99     if (fname2)
100     {
101         if (!strcmp(fname2, "-"))
102             dumpfile = stdout;
103         else
104             dumpfile = fopen(fname2, "w");
105     }
106
107     for (i = 0; i<sizeof(buf); i++)
108         buf[i] = rand() & 0xff;
109
110     for (j = 0; j<sizeof(buf)-1; j++)
111     {
112         Z_GDU *req;
113         char *mbuf;
114         ODR odr;
115
116         nmem_init();
117         odr = odr_createmem(ODR_DECODE);
118         if (fname)
119         {
120             int off = 0;
121             int fd =open(fname, O_TRUNC|O_CREAT|O_WRONLY, 0666);
122             if (fd == -1)
123             {
124                 yaz_log(LOG_ERRNO|LOG_FATAL, "open %s", fname);
125                 exit (1);
126             }
127             while (sizeof(buf)-j-off > 0)
128             {
129                 ssize_t wrote;
130                 wrote = write(fd, buf+off+j, sizeof(buf)-j-off);
131                 if (wrote <= 0) {
132                     yaz_log(LOG_ERRNO|LOG_FATAL, "write %s", fname);
133                     exit (1);
134                 }
135                 off += wrote;
136             }
137             if (close(fd) == -1)
138             {
139                 yaz_log(LOG_ERRNO|LOG_FATAL, "close %s", fname);
140                 exit (1);
141             }
142         }
143         mbuf = malloc(sizeof(buf)-j);
144         memcpy(mbuf, buf+j, sizeof(buf)-j);
145         odr_setbuf(odr, mbuf, sizeof(buf)-j, 0);
146         if (z_GDU(odr, &req, 0, 0))
147             estat[99]++;
148         else
149         {
150             int ex;
151             odr_geterrorx(odr, &ex);
152             estat[ex]++;
153         }
154         if (dumpfile)
155             odr_dumpBER(dumpfile, buf+j, sizeof(buf)-j);
156         free(mbuf);
157         odr_reset(odr);
158         odr_destroy(odr);
159         nmem_exit();
160     }
161     if (dumpfile && dumpfile != stdout)
162         fclose(dumpfile);
163 }
164
165 void sigint_handler(int x)
166 {
167     stop = 1;
168 }
169
170 int main(int argc, char **argv)
171 {
172     int start = 0, end = 10000000, ret, i, estat[100];
173     char *arg;
174     char *ber_fname = 0;
175     char *packet_fname = 0;
176
177     signal(SIGINT, sigint_handler);
178     signal(SIGTERM, sigint_handler);
179     for (i = 0; i<sizeof(estat)/sizeof(*estat); i++)
180         estat[i] = 0;
181
182     while ((ret = options("s:e:b:p:", argv, argc, &arg)) != -2)
183     {
184         switch (ret)
185         {
186         case 's':
187             start = atoi(arg);
188             break;
189         case 'e':
190             end = atoi(arg);
191             break;
192         case 'b':
193             ber_fname = arg;
194             break;
195         case 'p':
196             packet_fname = arg;
197             break;
198         case 0:
199             if (!strcmp(arg, "random"))
200             {
201                 i = start;
202                 while(!stop && (end == 0 || i < end))
203                 {
204                     srand(i*5111+1);
205                     if ((i % 50) == 0)
206                         printf ("\r[%d]", i); fflush(stdout);
207                     test_random(i, packet_fname, ber_fname, estat);
208                     i++;
209                 }
210             }
211             break;
212         default:
213             fprintf (stderr, "usage\n");
214             fprintf (stderr, " [-s start] [-e end] [-b berdump] [-p packetdump] random\n");
215             exit(1);
216         }
217     }
218     printf ("\n");
219     for (i = 0; i < sizeof(estat)/sizeof(*estat); i++)
220         if (estat[i])
221             printf ("%3d %9d\n", i, estat[i]);
222     exit(0);
223 }
224 /*
225  * Local variables:
226  * c-basic-offset: 4
227  * indent-tabs-mode: nil
228  * End:
229  * vim: shiftwidth=4 tabstop=8 expandtab
230  */
231