Apache HTTPD
aplibtool.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdio.h>
18#include <process.h>
19#include <string.h>
20#include <stdlib.h>
21#include <sys/types.h>
22#include <dirent.h>
23
24typedef char bool;
25#define false 0
26#define true (!false)
27
28bool silent = false;
29bool shared = false;
30bool export_all = false;
33
34#ifdef __EMX__
35# define SHELL_CMD "sh"
36# define CC "gcc"
37# define GEN_EXPORTS "emxexp"
38# define DEF2IMPLIB_CMD "emximp"
39# define SHARE_SW "-Zdll -Zmtd"
40# define USE_OMF true
41# define TRUNCATE_DLL_NAME
42# define DYNAMIC_LIB_EXT "dll"
43# define EXE_EXT ".exe"
44
45# if USE_OMF
46 /* OMF is the native format under OS/2 */
47# define STATIC_LIB_EXT "lib"
48# define OBJECT_EXT "obj"
49# define LIBRARIAN "emxomfar"
50# else
51 /* but the alternative, a.out, can fork() which is sometimes necessary */
52# define STATIC_LIB_EXT "a"
53# define OBJECT_EXT "o"
54# define LIBRARIAN "ar"
55# endif
56#endif
57
58
59typedef struct {
60 char *arglist[1024];
65 char *stub_name;
66 char *tmp_dirs[1024];
68 char *obj_files[1024];
71
72void parse_args(int argc, char *argv[], cmd_data_t *cmd_data);
73bool parse_long_opt(char *arg, cmd_data_t *cmd_data);
74int parse_short_opt(char *arg, cmd_data_t *cmd_data);
75bool parse_input_file_name(char *arg, cmd_data_t *cmd_data);
76bool parse_output_file_name(char *arg, cmd_data_t *cmd_data);
77void post_parse_fixup(cmd_data_t *cmd_data);
78bool explode_static_lib(char *lib, cmd_data_t *cmd_data);
79int execute_command(cmd_data_t *cmd_data);
80char *shell_esc(const char *str);
81void cleanup_tmp_dirs(cmd_data_t *cmd_data);
82void generate_def_file(cmd_data_t *cmd_data);
83char *nameof(char *fullpath);
84char *truncate_dll_name(char *path);
85
86
87int main(int argc, char *argv[])
88{
89 int rc;
90 cmd_data_t cmd_data;
91
92 memset(&cmd_data, 0, sizeof(cmd_data));
93 cmd_data.mode = mCompile;
94 cmd_data.output_type = otGeneral;
95
96 parse_args(argc, argv, &cmd_data);
97 rc = execute_command(&cmd_data);
98
99 if (rc == 0 && cmd_data.stub_name) {
100 fopen(cmd_data.stub_name, "w");
101 }
102
103 cleanup_tmp_dirs(&cmd_data);
104 return rc;
105}
106
107
108
109void parse_args(int argc, char *argv[], cmd_data_t *cmd_data)
110{
111 int a;
112 char *arg;
113 bool argused;
114
115 for (a=1; a < argc; a++) {
116 arg = argv[a];
117 argused = false;
118
119 if (arg[0] == '-') {
120 if (arg[1] == '-') {
121 argused = parse_long_opt(arg + 2, cmd_data);
122 } else if (arg[1] == 'o' && a+1 < argc) {
123 cmd_data->arglist[cmd_data->num_args++] = arg;
124 arg = argv[++a];
126 } else {
127 int num_used = parse_short_opt(arg + 1, cmd_data);
128 argused = num_used > 0;
129
130 if (num_used > 1) {
131 a += num_used - 1;
132 }
133 }
134 } else {
135 argused = parse_input_file_name(arg, cmd_data);
136 }
137
138 if (!argused) {
139 cmd_data->arglist[cmd_data->num_args++] = arg;
140 }
141 }
142
143 post_parse_fixup(cmd_data);
144}
145
146
147
148bool parse_long_opt(char *arg, cmd_data_t *cmd_data)
149{
150 char *equal_pos = strchr(arg, '=');
151 char var[50];
152 char value[500];
153
154 if (equal_pos) {
156 var[equal_pos - arg] = 0;
157 strcpy(value, equal_pos + 1);
158 } else {
159 strcpy(var, arg);
160 }
161
162 if (strcmp(var, "silent") == 0) {
163 silent = true;
164 } else if (strcmp(var, "mode") == 0) {
165 if (strcmp(value, "compile") == 0) {
166 cmd_data->mode = mCompile;
167 cmd_data->output_type = otObject;
168 }
169
170 if (strcmp(value, "link") == 0) {
171 cmd_data->mode = mLink;
172 }
173
174 if (strcmp(value, "install") == 0) {
175 cmd_data->mode = mInstall;
176 }
177 } else if (strcmp(var, "shared") == 0) {
178 shared = true;
179 } else if (strcmp(var, "export-all") == 0) {
180 export_all = true;
181 } else {
182 return false;
183 }
184
185 return true;
186}
187
188
189
190int parse_short_opt(char *arg, cmd_data_t *cmd_data)
191{
192 if (strcmp(arg, "export-dynamic") == 0) {
193 return 1;
194 }
195
196 if (strcmp(arg, "module") == 0) {
197 return 1;
198 }
199
200 if (strcmp(arg, "Zexe") == 0) {
201 return 1;
202 }
203
204 if (strcmp(arg, "avoid-version") == 0) {
205 return 1;
206 }
207
208 if (strcmp(arg, "prefer-pic") == 0) {
209 return 1;
210 }
211
212 if (strcmp(arg, "prefer-non-pic") == 0) {
213 return 1;
214 }
215
216 if (strcmp(arg, "version-info") == 0 ) {
217 return 2;
218 }
219
220 if (strcmp(arg, "no-install") == 0) {
221 return 1;
222 }
223
224 return 0;
225}
226
227
228
230{
231 char *ext = strrchr(arg, '.');
232 char *name = strrchr(arg, '/');
233 char *newarg;
234
235 if (!ext) {
236 return false;
237 }
238
239 ext++;
240
241 if (name == NULL) {
242 name = strrchr(arg, '\\');
243
244 if (name == NULL) {
245 name = arg;
246 } else {
247 name++;
248 }
249 } else {
250 name++;
251 }
252
253 if (strcmp(ext, "lo") == 0) {
254 newarg = (char *)malloc(strlen(arg) + 10);
255 strcpy(newarg, arg);
257 cmd_data->arglist[cmd_data->num_args++] = newarg;
258 cmd_data->obj_files[cmd_data->num_obj_files++] = newarg;
259 return true;
260 }
261
262 if (strcmp(ext, "la") == 0) {
263 newarg = (char *)malloc(strlen(arg) + 10);
264 strcpy(newarg, arg);
265 newarg[pathlen] = 0;
266 strcat(newarg, ".libs/");
267
268 if (strncmp(name, "lib", 3) == 0) {
269 name += 3;
270 }
271
273 ext = strrchr(newarg, '.') + 1;
274
275 if (shared && cmd_data->mode == mInstall) {
278 } else {
280 }
281
282 cmd_data->arglist[cmd_data->num_args++] = newarg;
283 return true;
284 }
285
286 if (strcmp(ext, "c") == 0) {
287 if (cmd_data->stub_name == NULL) {
288 cmd_data->stub_name = (char *)malloc(strlen(arg) + 4);
289 strcpy(cmd_data->stub_name, arg);
290 strcpy(strrchr(cmd_data->stub_name, '.') + 1, "lo");
291 }
292 }
293
294 if (strcmp(name, CC) == 0 || strcmp(name, CC EXE_EXT) == 0) {
295 if (cmd_data->output_type == otGeneral) {
296 cmd_data->output_type = otObject;
297 }
298 }
299
300 return false;
301}
302
303
304
306{
307 char *name = strrchr(arg, '/');
308 char *ext = strrchr(arg, '.');
309 char *newarg = NULL, *newext;
310
311 if (name == NULL) {
312 name = strrchr(arg, '\\');
313
314 if (name == NULL) {
315 name = arg;
316 } else {
317 name++;
318 }
319 } else {
320 name++;
321 }
322
323 if (!ext) {
324 cmd_data->stub_name = arg;
325 cmd_data->output_type = otProgram;
326 newarg = (char *)malloc(strlen(arg) + 5);
327 strcpy(newarg, arg);
329 cmd_data->arglist[cmd_data->num_args++] = newarg;
330 cmd_data->output_name = newarg;
331 return true;
332 }
333
334 ext++;
335
336 if (strcmp(ext, "la") == 0) {
337 cmd_data->stub_name = arg;
339 newarg = (char *)malloc(strlen(arg) + 10);
340 mkdir(".libs", 0);
341 strcpy(newarg, ".libs/");
342
343 if (strncmp(arg, "lib", 3) == 0) {
344 arg += 3;
345 }
346
347 strcat(newarg, arg);
348 newext = strrchr(newarg, '.') + 1;
350
351#ifdef TRUNCATE_DLL_NAME
352 if (shared) {
354 }
355#endif
356
357 cmd_data->arglist[cmd_data->num_args++] = newarg;
358 cmd_data->output_name = newarg;
359 return true;
360 }
361
362 if (strcmp(ext, "lo") == 0) {
363 cmd_data->stub_name = arg;
364 cmd_data->output_type = otObject;
365 newarg = (char *)malloc(strlen(arg) + 2);
366 strcpy(newarg, arg);
367 ext = strrchr(newarg, '.') + 1;
369 cmd_data->arglist[cmd_data->num_args++] = newarg;
370 cmd_data->output_name = newarg;
371 return true;
372 }
373
374 return false;
375}
376
377
378
380{
381 int a;
382 char *arg;
383 char *ext;
384
385 if (cmd_data->output_type == otStaticLibrary && cmd_data->mode == mLink) {
386 /* We do a real hatchet job on the args when making a static library
387 * removing all compiler switches & any other cruft that ar won't like
388 * We also need to explode any libraries listed
389 */
390
391 for (a=0; a < cmd_data->num_args; a++) {
392 arg = cmd_data->arglist[a];
393
394 if (arg) {
395 ext = strrchr(arg, '.');
396
397 if (ext) {
398 ext++;
399 }
400
401 if (arg[0] == '-') {
402 cmd_data->arglist[a] = NULL;
403
404 if (strcmp(arg, "-rpath") == 0 && a+1 < cmd_data->num_args) {
405 cmd_data->arglist[a+1] = NULL;
406 }
407
408 if (strcmp(arg, "-R") == 0 && a+1 < cmd_data->num_args) {
409 cmd_data->arglist[a+1] = NULL;
410 }
411
412 if (strcmp(arg, "-version-info") == 0 && a+1 < cmd_data->num_args) {
413 cmd_data->arglist[a+1] = NULL;
414 }
415
416 if (strcmp(arg, "-Zstack") == 0 && a+1 < cmd_data->num_args) {
417 cmd_data->arglist[a+1] = NULL;
418 }
419
420 if (strcmp(arg, "-o") == 0) {
421 a++;
422 }
423 }
424
425 if (strcmp(arg, CC) == 0 || strcmp(arg, CC EXE_EXT) == 0) {
426 cmd_data->arglist[a] = LIBRARIAN " cr";
427 }
428
429 if (ext) {
430 if (strcmp(ext, "h") == 0 || strcmp(ext, "c") == 0) {
431 /* ignore source files, they don't belong in a library */
432 cmd_data->arglist[a] = NULL;
433 }
434
435 if (strcmp(ext, STATIC_LIB_EXT) == 0) {
436 cmd_data->arglist[a] = NULL;
437 explode_static_lib(arg, cmd_data);
438 }
439 }
440 }
441 }
442 }
443
444 if (cmd_data->output_type == otDynamicLibrary) {
445 for (a=0; a < cmd_data->num_args; a++) {
446 arg = cmd_data->arglist[a];
447
448 if (arg) {
449 if (strcmp(arg, "-rpath") == 0 && a+1 < cmd_data->num_args) {
450 cmd_data->arglist[a] = NULL;
451 cmd_data->arglist[a+1] = NULL;
452 }
453 }
454 }
455
456 if (export_all) {
457 generate_def_file(cmd_data);
458 }
459 }
460
461#if USE_OMF
462 if (cmd_data->output_type == otObject ||
463 cmd_data->output_type == otProgram ||
464 cmd_data->output_type == otDynamicLibrary) {
465 cmd_data->arglist[cmd_data->num_args++] = "-Zomf";
466 }
467#endif
468
469 if (shared && (cmd_data->output_type == otObject || cmd_data->output_type == otDynamicLibrary)) {
470 cmd_data->arglist[cmd_data->num_args++] = SHARE_SW;
471 }
472}
473
474
475
477{
478 int target = 0;
479 char *command;
480 int a, total_len = 0;
481 char *args[4];
482
483 for (a=0; a < cmd_data->num_args; a++) {
484 if (cmd_data->arglist[a]) {
485 total_len += strlen(cmd_data->arglist[a]) + 1;
486 }
487 }
488
489 command = (char *)malloc( total_len );
490 command[0] = 0;
491
492 for (a=0; a < cmd_data->num_args; a++) {
493 if (cmd_data->arglist[a]) {
494 strcat(command, cmd_data->arglist[a]);
495 strcat(command, " ");
496 }
497 }
498
499 command[strlen(command)-1] = 0;
500
501 if (!silent) {
502 puts(command);
503 }
504
505 cmd_data->num_args = target;
506 cmd_data->arglist[cmd_data->num_args] = NULL;
508
509 args[0] = SHELL_CMD;
510 args[1] = "-c";
511 args[2] = command;
512 args[3] = NULL;
513 return spawnvp(P_WAIT, args[0], args);
514}
515
516
517
518char *shell_esc(const char *str)
519{
520 char *cmd;
521 unsigned char *d;
522 const unsigned char *s;
523
524 cmd = (char *)malloc(2 * strlen(str) + 1);
525 d = (unsigned char *)cmd;
526 s = (const unsigned char *)str;
527
528 for (; *s; ++s) {
529 if (*s == '"' || *s == '\\') {
530 *d++ = '\\';
531 }
532 *d++ = *s;
533 }
534
535 *d = '\0';
536 return cmd;
537}
538
539
540
541bool explode_static_lib(char *lib, cmd_data_t *cmd_data)
542{
543 char tmpdir[1024];
544 char savewd[1024];
545 char cmd[1024];
546 char *name;
547 DIR *dir;
548 struct dirent *entry;
549
550 strcpy(tmpdir, lib);
551 strcat(tmpdir, ".exploded");
552
553 mkdir(tmpdir, 0);
554 cmd_data->tmp_dirs[cmd_data->num_tmp_dirs++] = strdup(tmpdir);
555 getcwd(savewd, sizeof(savewd));
556
557 if (chdir(tmpdir) != 0)
558 return false;
559
560 strcpy(cmd, LIBRARIAN " x ");
561 name = strrchr(lib, '/');
562
563 if (name) {
564 name++;
565 } else {
566 name = lib;
567 }
568
569 strcat(cmd, "../");
570 strcat(cmd, name);
571 system(cmd);
572 chdir(savewd);
573 dir = opendir(tmpdir);
574
575 while ((entry = readdir(dir)) != NULL) {
576 if (entry->d_name[0] != '.') {
577 strcpy(cmd, tmpdir);
578 strcat(cmd, "/");
579 strcat(cmd, entry->d_name);
580 cmd_data->arglist[cmd_data->num_args++] = strdup(cmd);
581 }
582 }
583
584 closedir(dir);
585 return true;
586}
587
588
589
591{
592 DIR *dir;
593 struct dirent *entry;
594 char fullname[1024];
595
597
598 if (dir == NULL)
599 return;
600
601 while ((entry = readdir(dir)) != NULL) {
602 if (entry->d_name[0] != '.') {
604 strcat(fullname, "/");
605 strcat(fullname, entry->d_name);
606 remove(fullname);
607 }
608 }
609
610 rmdir(dirname);
611}
612
613
614
616{
617 int d;
618
619 for (d=0; d < cmd_data->num_tmp_dirs; d++) {
620 cleanup_tmp_dir(cmd_data->tmp_dirs[d]);
621 }
622}
623
624
625
627{
628 char def_file[1024];
629 char implib_file[1024];
630 char *ext;
631 FILE *hDef;
632 char *export_args[1024];
633 int num_export_args = 0;
634 char *cmd;
635 int cmd_size = 0;
636 int a;
637
638 if (cmd_data->output_name) {
639 strcpy(def_file, cmd_data->output_name);
640 strcat(def_file, ".def");
641 hDef = fopen(def_file, "w");
642
643 if (hDef != NULL) {
644 fprintf(hDef, "LIBRARY '%s' INITINSTANCE\n", nameof(cmd_data->output_name));
645 fprintf(hDef, "DATA NONSHARED\n");
646 fprintf(hDef, "EXPORTS\n");
647 fclose(hDef);
648
649 for (a=0; a < cmd_data->num_obj_files; a++) {
650 cmd_size += strlen(cmd_data->obj_files[a]) + 1;
651 }
652
653 cmd_size += strlen(GEN_EXPORTS) + strlen(def_file) + 3;
654 cmd = (char *)malloc(cmd_size);
656
657 for (a=0; a < cmd_data->num_obj_files; a++) {
658 strcat(cmd, " ");
659 strcat(cmd, cmd_data->obj_files[a] );
660 }
661
662 strcat(cmd, ">>");
664 puts(cmd);
670 cmd_data->arglist[cmd_data->num_args++] = strdup(def_file);
671
672 /* Now make an import library for the dll */
673 num_export_args = 0;
676
677 strcpy(implib_file, ".libs/");
678 strcat(implib_file, cmd_data->stub_name);
679 ext = strrchr(implib_file, '.');
680
681 if (ext)
682 *ext = 0;
683
684 strcat(implib_file, ".");
686
691 }
692 }
693}
694
695
696
697/* returns just a file's name without path or extension */
698char *nameof(char *fullpath)
699{
700 char buffer[1024];
701 char *ext;
702 char *name = strrchr(fullpath, '/');
703
704 if (name == NULL) {
705 name = strrchr(fullpath, '\\');
706 }
707
708 if (name == NULL) {
709 name = fullpath;
710 } else {
711 name++;
712 }
713
715 ext = strrchr(buffer, '.');
716
717 if (ext) {
718 *ext = 0;
719 return strdup(buffer);
720 }
721
722 return name;
723}
724
725
726
728{
729 /* Cut DLL name down to 8 characters after removing any mod_ prefix */
730 char *tmppath = strdup(path);
731 char *newname = strrchr(tmppath, '/') + 1;
732 char *ext = strrchr(tmppath, '.');
733 int len;
734
735 if (ext == NULL)
736 return tmppath;
737
738 len = ext - newname;
739
740 if (strncmp(newname, "mod_", 4) == 0) {
741 strcpy(newname, newname + 4);
742 len -= 4;
743 }
744
745 if (len > 8) {
746 strcpy(newname + 8, strchr(newname, '.'));
747 }
748
749 return tmppath;
750}
const char apr_size_t len
Definition ap_regex.h:187
bool parse_long_opt(char *arg, cmd_data_t *cmd_data)
Definition aplibtool.c:148
mode_t
Definition aplibtool.c:31
@ mLink
Definition aplibtool.c:31
@ mCompile
Definition aplibtool.c:31
@ mInstall
Definition aplibtool.c:31
char * shell_esc(const char *str)
Definition aplibtool.c:518
bool explode_static_lib(char *lib, cmd_data_t *cmd_data)
Definition aplibtool.c:541
char * nameof(char *fullpath)
Definition aplibtool.c:698
int parse_short_opt(char *arg, cmd_data_t *cmd_data)
Definition aplibtool.c:190
char * truncate_dll_name(char *path)
Definition aplibtool.c:727
bool parse_input_file_name(char *arg, cmd_data_t *cmd_data)
Definition aplibtool.c:229
void generate_def_file(cmd_data_t *cmd_data)
Definition aplibtool.c:626
bool parse_output_file_name(char *arg, cmd_data_t *cmd_data)
Definition aplibtool.c:305
int execute_command(cmd_data_t *cmd_data)
Definition aplibtool.c:476
bool shared
Definition aplibtool.c:29
void parse_args(int argc, char *argv[], cmd_data_t *cmd_data)
Definition aplibtool.c:109
bool export_all
Definition aplibtool.c:30
bool silent
Definition aplibtool.c:28
char bool
Definition aplibtool.c:24
output_type_t
Definition aplibtool.c:32
@ otProgram
Definition aplibtool.c:32
@ otGeneral
Definition aplibtool.c:32
@ otObject
Definition aplibtool.c:32
@ otDynamicLibrary
Definition aplibtool.c:32
@ otStaticLibrary
Definition aplibtool.c:32
void cleanup_tmp_dirs(cmd_data_t *cmd_data)
Definition aplibtool.c:615
void post_parse_fixup(cmd_data_t *cmd_data)
Definition aplibtool.c:379
void cleanup_tmp_dir(char *dirname)
Definition aplibtool.c:590
char * strdup(const char *str)
apr_size_t const unsigned char unsigned int unsigned int d
Definition apr_siphash.h:72
request_rec int int apr_table_t const char * path
void const char * arg
Definition http_vhost.h:63
apr_bucket apr_bucket_brigade * a
apr_redis_t * rc
Definition apr_redis.h:173
apr_size_t size
const char * dirname
const char * value
Definition apr_env.h:51
char * buffer
apr_pool_t int argc
Definition apr_getopt.h:104
apr_dir_t * dir
const char * s
Definition apr_strings.h:95
apr_cmdtype_e cmd
const char const char *const * args
const char * argv[3]
return NULL
Definition mod_so.c:359
int main(void)
Definition occhild.c:9
static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, step_vars_storage *step_vars)
Definition sed1.c:766
char * name
char * obj_files[1024]
Definition aplibtool.c:68
char * stub_name
Definition aplibtool.c:65
char * tmp_dirs[1024]
Definition aplibtool.c:66
enum output_type_t output_type
Definition aplibtool.c:63
int num_obj_files
Definition aplibtool.c:69
int num_args
Definition aplibtool.c:61
enum mode_t mode
Definition aplibtool.c:62
char * output_name
Definition aplibtool.c:64
char * arglist[1024]
Definition aplibtool.c:60
int num_tmp_dirs
Definition aplibtool.c:67
#define var
#define str