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