/[gentoo-projects]/portage-utils/q.c
Gentoo

Contents of /portage-utils/q.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.53 - (show annotations) (download) (as text)
Tue Feb 25 21:30:50 2014 UTC (5 months ago) by vapier
Branch: MAIN
Changes since 1.52: +9 -8 lines
File MIME type: text/x-csrc
add support for setting ROOT via cmdline --root flag http://crbug.com/336871

1 /*
2 * Copyright 2005-2010 Gentoo Foundation
3 * Distributed under the terms of the GNU General Public License v2
4 * $Header: /var/cvsroot/gentoo-projects/portage-utils/q.c,v 1.52 2011/03/17 03:32:51 vapier Exp $
5 *
6 * Copyright 2005-2010 Ned Ludd - <solar@gentoo.org>
7 * Copyright 2005-2010 Mike Frysinger - <vapier@gentoo.org>
8 */
9
10 #define Q_FLAGS "irmM:" COMMON_FLAGS
11 static struct option const q_long_opts[] = {
12 {"install", no_argument, NULL, 'i'},
13 {"reinitialize", no_argument, NULL, 'r'},
14 {"metacache", no_argument, NULL, 'm'},
15 {"modpath", a_argument, NULL, 'M'},
16 COMMON_LONG_OPTS
17 };
18 static const char * const q_opts_help[] = {
19 "Install symlinks for applets",
20 "Reinitialize ebuild cache",
21 "Reinitialize metadata cache",
22 "Module path",
23 COMMON_OPTS_HELP
24 };
25 static const char q_rcsid[] = "$Id: q.c,v 1.52 2011/03/17 03:32:51 vapier Exp $";
26 #define q_usage(ret) usage(ret, Q_FLAGS, q_long_opts, q_opts_help, lookup_applet_idx("q"))
27
28 static APPLET lookup_applet(const char *applet)
29 {
30 unsigned int i;
31
32 if (strlen(applet) < 1)
33 return NULL;
34
35 for (i = 0; applets[i].name; ++i) {
36 if (strcmp(applets[i].name, applet) == 0) {
37 DBG("found applet %s at %p", applets[i].name, applets[i].func);
38 argv0 = applets[i].name;
39 if (i && applets[i].desc != NULL) ++argv0; /* chop the leading 'q' */
40 return applets[i].func;
41 }
42 }
43
44 /* No applet found? Search by shortname then... */
45 DBG("Looking up applet (%s) by short name", applet);
46 for (i = 1; applets[i].desc != NULL; ++i) {
47 if (strcmp(applets[i].name + 1, applet) == 0) {
48 DBG("found applet by short name %s", applets[i].name);
49 argv0 = applets[i].name + 1;
50 return applets[i].func;
51 }
52 }
53 /* still nothing ? those bastards ... */
54 warn("Unknown applet '%s'", applet);
55 return NULL;
56 }
57
58 int lookup_applet_idx(const char *applet)
59 {
60 unsigned int i;
61 for (i = 0; applets[i].name; i++)
62 if (strcmp(applets[i].name, applet) == 0)
63 return i;
64 return 0;
65 }
66
67 int q_main(int argc, char **argv)
68 {
69 int i, install;
70 const char *p;
71 APPLET func;
72
73 if (argc == 0)
74 return 1;
75
76 argv0 = p = basename(argv[0]);
77
78 if ((func = lookup_applet(p)) == NULL)
79 return 1;
80 if (strcmp("q", p) != 0)
81 return (func)(argc, argv);
82
83 if (argc == 1)
84 q_usage(EXIT_FAILURE);
85
86 install = 0;
87
88 while ((i = GETOPT_LONG(Q, q, "+")) != -1) {
89 switch (i) {
90 COMMON_GETOPTS_CASES(q)
91 case 'M': modpath = optarg; break;
92 case 'm': reinitialize_metacache = 1; break;
93 case 'r': reinitialize = 1; break;
94 case 'i': install = 1; break;
95 }
96 }
97
98 if (install) {
99 char buf[_Q_PATH_MAX];
100 const char *prog;
101 ssize_t rret;
102 int fd, ret;
103
104 if (!quiet)
105 printf("Installing symlinks:\n");
106
107 rret = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
108 if (rret == -1) {
109 char *ptr = which("q");
110 if (ptr == NULL) {
111 warnfp("haha no symlink love for you");
112 return 1;
113 }
114 strncpy(buf, ptr, sizeof(buf));
115 buf[sizeof(buf) - 1] = '\0';
116 } else
117 buf[rret] = '\0';
118
119 prog = basename(buf);
120 fd = open(dirname(buf), O_RDONLY|O_CLOEXEC);
121 if (fd < 0) {
122 warnfp("chdir(%s) failed", buf);
123 return 1;
124 }
125
126 ret = 0;
127 for (i = 1; applets[i].desc; ++i) {
128 int r = symlinkat(prog, fd, applets[i].name);
129 if (!quiet)
130 printf(" %s ...\t[%s]\n", applets[i].name, r ? strerror(errno) : "OK");
131 if (r && errno != EEXIST)
132 ret = 1;
133 }
134
135 close(fd);
136
137 return ret;
138 }
139
140 if (reinitialize || reinitialize_metacache)
141 return 0;
142 if (argc == optind)
143 q_usage(EXIT_FAILURE);
144 if ((func = lookup_applet(argv[optind])) == NULL)
145 return 1;
146
147 /* In case of "q --option ... appletname ...", remove appletname from the
148 * applet's args. */
149 if (optind > 1) {
150 argv[0] = argv[optind];
151 for (i = optind; i < argc; ++i)
152 argv[i] = argv[i + 1];
153 } else
154 ++argv;
155
156 optind = 0; /* reset so the applets can call getopt */
157
158 return (func)(argc - 1, argv);
159 }
160
161 static int run_applet_l(const char *arg, ...)
162 {
163 int (*applet)(int, char **);
164 va_list ap;
165 int ret, optind_saved, argc;
166 char **argv;
167 const char *argv0_saved;
168
169 optind_saved = optind;
170 argv0_saved = argv0;
171
172 applet = lookup_applet(arg);
173 if (!applet)
174 return -1;
175
176 /* This doesn't NULL terminate argv, but you should be using argc */
177 va_start(ap, arg);
178 argc = 0;
179 argv = NULL;
180 while (arg) {
181 argv = xrealloc(argv, sizeof(*argv) * ++argc);
182 argv[argc - 1] = xstrdup(arg);
183 arg = va_arg(ap, const char *);
184 }
185 va_end(ap);
186
187 optind = 0;
188 argv0 = argv[0];
189 ret = applet(argc, argv);
190
191 while (argc--)
192 free(argv[argc]);
193 free(argv);
194
195 optind = optind_saved;
196 argv0 = argv0_saved;
197
198 return ret;
199 }

  ViewVC Help
Powered by ViewVC 1.1.20