fix format string (inspired by issue #4945)
[asterisk/asterisk.git] / build_tools / vercomp.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * A simple program version comparison tool.
5  * 
6  * Copyright (C) 2005, Steven Michael Murphy (murf at e-tools dot com).
7  *
8  * This program is free software, distributed under the terms of
9  * the GNU General Public License
10  */
11
12 /* vercomp.c
13    args: <program> <comparison> <version>
14
15         where:
16
17    program = path to program (bison or flex)
18    comparison = ">", "<", "<=", ">=", "="  -- depending on shell, you may have to use backslash escapes
19    version = a version compare against, say 1.875, or 2.5.4, or whatever.
20
21 */
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26
27 char *program_version[5];
28 char *arg_version[5];
29
30 void get_program_version_string(char *command, char *output)
31 {
32         char cbuf[8000];
33         char pbuf[8000];
34         char zbuf[8000];
35         char *res;
36         FILE *p1;
37
38         zbuf[0] = 0;
39         
40         sprintf( cbuf, "%s --version", command );
41         p1 = popen(cbuf, "r");
42         if( !p1 )
43         {
44                 fprintf(stderr,"vercomp: Could not execute the command: %s\n", command);
45                 exit(125);
46         }
47         /* the first line is the magic one */
48         res = fgets(zbuf, 8000, p1);
49         /* clear the trailing blank */
50         if( zbuf[strlen(zbuf)-1] == '\n' )
51                 zbuf[strlen(zbuf)-1] = 0;
52         /* the rest is cruft, just empty the input stream */
53         while( res )
54         {
55                 res = fgets(pbuf, 8000, p1);
56         }
57         /* close the stream. Hopefully, we have what we need */
58         pclose(p1);
59         /* all we want is the last "word"-- so find the last blank, and grab everything after that */
60
61         res = strrchr(zbuf,' ');
62         if( !res )
63         {
64                 fprintf(stderr,"Something is wrong with the version string: %s\n", zbuf);
65                 exit(124);
66         }
67         strcpy(output,res+1);
68 }
69
70
71 void extract_version(char *ver_string, char **where)
72 {
73         int i=0;
74         char *p=ver_string;
75         
76         while( p && *p )
77         {
78                 where[i++] = p;
79                 p = strchr(p,'.');
80                 if( p )
81                 {
82                         *p= 0;
83                         p++;
84                 }
85         }
86 }
87
88 void compare_versions(char *compare_func)
89 {
90         int i;
91         
92         for(i=0;i<5;i++)
93         {
94                 /* start out at the beginning, then go to the end */
95                 if( program_version[i] && arg_version[i] && *program_version[i] && *arg_version[i] )
96                 {
97                         
98                         if( strlen(program_version[i]) == strspn(program_version[i],"0123456789")
99                                 && strlen(arg_version[i]) == strspn(arg_version[i],"0123456789") )
100                         {
101                                 /* just pure numbers -- do a numeric compare */
102                                 int pv = atoi(program_version[i]);
103                                 int av = atoi(arg_version[i]);
104                                 
105                                 if( pv < av )
106                                 {
107                                         if( !strcmp(compare_func,"=") )
108                                         {
109                                                 printf("false\n");
110                                                 exit(0);
111                                         }
112                                         else if( !strcmp(compare_func, ">") )
113                                         {
114                                                 printf("false\n");
115                                                 exit(0);
116                                         }
117                                         else if( !strcmp(compare_func, "<") )
118                                         {
119                                                 printf("true\n");
120                                                 exit(0);
121                                         }
122                                         else if( !strcmp(compare_func, ">=") )
123                                         {
124                                                 printf("false\n");
125                                                 exit(0);
126                                         }
127                                         else if( !strcmp(compare_func, "<=") )
128                                         {
129                                                 printf("true\n");
130                                                 exit(0);
131                                         }
132                                 }
133                                 else if( pv > av )
134                                 {
135                                         if( !strcmp(compare_func,"=") )
136                                         {
137                                                 printf("false\n");
138                                                 exit(0);
139                                         }
140                                         else if( !strcmp(compare_func, ">") )
141                                         {
142                                                 printf("true\n");
143                                                 exit(0);
144                                         }
145                                         else if( !strcmp(compare_func, "<") )
146                                         {
147                                                 printf("false\n");
148                                                 exit(0);
149                                         }
150                                         else if( !strcmp(compare_func, ">=") )
151                                         {
152                                                 printf("true\n");
153                                                 exit(0);
154                                         }
155                                         else if( !strcmp(compare_func, "<=") )
156                                         {
157                                                 printf("false\n");
158                                                 exit(0);
159                                         }
160                                 }
161                         }
162                         else
163                         {
164                                 /* other junk thrown in -- do string compare */
165                                 int res = strcmp(program_version[i], arg_version[i]);
166                                 if( res < 0 ) /* prog is less than arg */
167                                 {
168                                         if( !strcmp(compare_func,"=") )
169                                         {
170                                                 printf("false\n");
171                                                 exit(0);
172                                         }
173                                         else if( !strcmp(compare_func, ">") )
174                                         {
175                                                 printf("false\n");
176                                                 exit(0);
177                                         }
178                                         else if( !strcmp(compare_func, "<") )
179                                         {
180                                                 printf("true\n");
181                                                 exit(0);
182                                         }
183                                         else if( !strcmp(compare_func, ">=") )
184                                         {
185                                                 printf("false\n");
186                                                 exit(0);
187                                         }
188                                         else if( !strcmp(compare_func, "<=") )
189                                         {
190                                                 printf("true\n");
191                                                 exit(0);
192                                         }
193                                 }
194                                 else if( res > 0 ) /* prog is greater than arg */
195                                 {
196                                         if( !strcmp(compare_func,"=") )
197                                         {
198                                                 printf("false\n");
199                                                 exit(0);
200                                         }
201                                         else if( !strcmp(compare_func, ">") )
202                                         {
203                                                 printf("true\n");
204                                                 exit(0);
205                                         }
206                                         else if( !strcmp(compare_func, "<") )
207                                         {
208                                                 printf("false\n");
209                                                 exit(0);
210                                         }
211                                         else if( !strcmp(compare_func, ">=") )
212                                         {
213                                                 printf("true\n");
214                                                 exit(0);
215                                         }
216                                         else if( !strcmp(compare_func, "<=") )
217                                         {
218                                                 printf("false\n");
219                                                 exit(0);
220                                         }
221                                 }
222                         }
223                 }
224                 else if( program_version[i] && *program_version[i] )
225                 {
226                         if( !strcmp(compare_func,"=") )
227                         {
228                                 printf("false\n");
229                                 exit(0);
230                         }
231                         else if( !strcmp(compare_func, ">") )
232                         {
233                                 printf("true\n");
234                                 exit(0);
235                         }
236                         else if( !strcmp(compare_func, "<") )
237                         {
238                                 printf("false\n");
239                                 exit(0);
240                         }
241                         else if( !strcmp(compare_func, ">=") )
242                         {
243                                 printf("true\n");
244                                 exit(0);
245                         }
246                         else if( !strcmp(compare_func, "<=") )
247                         {
248                                 printf("false\n");
249                                 exit(0);
250                         }
251                         
252                 }
253                 else if( arg_version[i] && *arg_version[i] )
254                 {
255                         if( !strcmp(compare_func,"=") )
256                         {
257                                 printf("false\n");
258                                 exit(0);
259                         }
260                         else if( !strcmp(compare_func, ">") )
261                         {
262                                 printf("false\n");
263                                 exit(0);
264                         }
265                         else if( !strcmp(compare_func, "<") )
266                         {
267                                 printf("true\n");
268                                 exit(0);
269                         }
270                         else if( !strcmp(compare_func, ">=") )
271                         {
272                                 printf("false\n");
273                                 exit(0);
274                         }
275                         else if( !strcmp(compare_func, "<=") )
276                         {
277                                 printf("true\n");
278                                 exit(0);
279                         }
280                 }
281                 else
282                         break;
283         }
284         if( !strcmp(compare_func,"=") )
285         {
286                 printf("true\n");
287                 exit(0);
288         }
289         else if( !strcmp(compare_func, ">") )
290         {
291                 printf("false\n");
292                 exit(0);
293         }
294         else if( !strcmp(compare_func, "<") )
295         {
296                 printf("false\n");
297                 exit(0);
298         }
299         else if( !strcmp(compare_func, ">=") )
300         {
301                 printf("true\n");
302                 exit(0);
303         }
304         else if( !strcmp(compare_func, "<=") )
305         {
306                 printf("true\n");
307                 exit(0);
308         }
309 }
310
311 void usage(void)
312 {
313         printf("Usage: <program-path> <comparison> <version>\n\
314 \n\
315         where:\n\
316 \n\
317    program-path = path to program (bison or flex)\n\
318    comparison = '>', '<', '<=', '>=', '='  -- depending on shell, you may have to use backslash escapes\n\
319    version = a version compare against, say 1.875, or 2.5.4, or whatever.\n\n");
320 }
321
322
323 int main(int argc, char **argv)
324 {
325         char program_version_string[8000];
326         
327         /* before starting, check args and make sure all is OK */
328         if( argc < 4 || argc > 4 )
329         {
330                 usage();
331                 exit(-256);
332         }
333         if ( strcmp(argv[2],"=") && strcmp(argv[2],">") && strcmp(argv[2],"<") && strcmp(argv[2],">=") && strcmp(argv[2],"<=") )
334         {
335                 fprintf(stderr,"vercomp: ILLEGAL input Comparison value: %s\n\n", argv[2]);
336                 usage();
337                 exit(-256);
338         }
339                  
340         /* first, extract a version from the command line arg */
341         extract_version(argv[3], arg_version);
342
343         /* next, extract a version from the command line */
344         get_program_version_string(argv[1], program_version_string);
345         extract_version(program_version_string, program_version);
346         
347         /* next compare and return result */
348         compare_versions(argv[2]);
349         /* the above func shouldn't return */
350 }