Imported Upstream version 0.16
[platform/upstream/chrpath.git] / main.c
1 /*
2  * Author: Petter Reinholdtsen <pere@hungry.com>
3  * date:   2001-01-20
4  *
5  * Alter ELF rpath information (insert, modify, remove).
6  *
7  * Based on source from Peeter Joot <peeterj@ca.ibm.com> and Geoffrey
8  * Keating <geoffk@ozemail.com.au>.
9  */
10
11 #ifdef HAVE_CONFIG_H
12 #  include "config.h"
13 #endif
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18 #ifdef HAVE_GETOPT_H
19 #include <getopt.h>
20 #endif
21 #include "protos.h"
22
23 #ifdef HAVE_GETOPT_LONG
24 #  define GETOPT_LONG getopt_long
25
26 static struct option long_options[] =
27 {
28   {"convert",   0, 0, 'c'},
29   {"delete",    0, 0, 'd'},
30   {"help",      0, 0, 'h'},
31   {"keepgoing", 0, 0, 'k'},
32   {"list",      0, 0, 'l'},
33   {"replace",   1, 0, 'r'},
34   {"version",   0, 0, 'v'},
35   {0, 0, 0, 0}
36 };
37
38 #else /* not HAVE_GETOPT_LONG */
39 #  define GETOPT_LONG(argc,argv,optstr,lopts,lidx) getopt(argc,argv,optstr)
40 #endif /* not HAVE_GETOPT_LONG */
41
42 static void
43 usage(char *progname)
44 {
45   printf("Usage: %s [-v|-d|-c|-r <path>] <program> [<program> ...]\n\n",
46          progname);
47   printf("   -v|--version                Display program version number\n");
48   printf("   -d|--delete                 Delete current rpath/runpath setting\n");
49 #if defined(DT_RUNPATH)
50   printf("   -c|--convert                Convert rpath to runpath\n");
51 #endif /* DT_RUNPATH */
52   printf("   -r <path>|--replace <path>  Replace current rpath/runpath setting\n");
53   printf("                               with the path given\n");
54   printf("   -l|--list                   List the current rpath/runpath (default)\n");
55   printf("   -k|--keepgoing              Do not fail on first error\n");
56   printf("   -h|--help                   Show this usage information.\n");
57 #ifndef HAVE_GETOPT_LONG
58   printf("\n *** The long options are not available on this platform");
59 #endif /* not HAVE_GETOPT_LONG */
60 #if !defined(DT_RUNPATH)
61   printf("\n *** There is no support for runpath on this platform");
62 #endif /* DT_RUNPATH */
63   printf("\n");
64 }
65
66 int
67 main(int argc, char * const argv[])
68 {
69   int retval = 0;
70   int convert = 0;      /* convert to given type */
71   int remove = 0;       /* remove or not */
72   int keep_going = 0;   /* Break on first error, or keep going? */
73   char *newpath = NULL; /* insert this path */
74   int opt;
75 #ifdef HAVE_GETOPT_LONG
76   int option_index = 0;
77 #endif /* HAVE_GETOPT_LONG */
78
79   if (argc < 2)
80     {
81       usage(argv[0]);
82       return 1;
83     }
84
85   do {
86     opt = GETOPT_LONG(argc, argv, "cdhklr:v", long_options, &option_index);
87     switch (opt)
88       {
89 #if defined(DT_RUNPATH)
90       case 'c':
91         convert = 1;
92         break;
93 #endif /* DT_RUNPATH */
94       case 'd':
95         remove = 1;
96         break;
97       case 'k':
98         keep_going = 1;
99         break;
100       case 'r':
101         newpath = optarg;
102         break;
103       case 'v':
104         printf("%s version %s\n", PACKAGE, VERSION);
105         exit(0);
106         break;
107       case 'l': /* This is the default action */
108         newpath = NULL;
109         break;
110       case -1:
111         break;
112       default:
113         printf("Invalid argument '%c'\n", opt);
114         /* Fall through */
115       case 'h':
116         usage(argv[0]);
117         exit(0);
118         break;
119       }
120   } while (-1 != opt);
121
122   while (optind < argc && (!retval || keep_going))
123     {
124       if (remove)
125         retval |= killrpath(argv[optind++]);
126       else
127         /* list by default, replace if path is set */
128         retval |= chrpath(argv[optind++], newpath, convert);
129     }
130
131   return retval;
132 }