comparison cli-runopts.c @ 1170:ff9bd50f1457

Bundling for dbclient
author Guilhem Moulin <guilhem@fripost.org>
date Mon, 23 Nov 2015 22:28:56 +0800
parents 1b583b2994ba
children c745f720ae2e
comparison
equal deleted inserted replaced
1169:41a5820cab8b 1170:ff9bd50f1457
103 } 103 }
104 104
105 void cli_getopts(int argc, char ** argv) { 105 void cli_getopts(int argc, char ** argv) {
106 unsigned int i, j; 106 unsigned int i, j;
107 char ** next = 0; 107 char ** next = 0;
108 enum {
109 #ifdef ENABLE_CLI_PUBKEY_AUTH
110 OPT_AUTHKEY,
111 #endif
112 #ifdef ENABLE_CLI_LOCALTCPFWD
113 OPT_LOCALTCPFWD,
114 #endif
115 #ifdef ENABLE_CLI_REMOTETCPFWD
116 OPT_REMOTETCPFWD,
117 #endif
118 #ifdef ENABLE_CLI_NETCAT
119 OPT_NETCAT,
120 #endif
121 /* a flag (no arg) if 'next' is NULL, a string-valued option otherwise */
122 OPT_OTHER
123 } opt;
108 unsigned int cmdlen; 124 unsigned int cmdlen;
109 #ifdef ENABLE_CLI_PUBKEY_AUTH
110 int nextiskey = 0; /* A flag if the next argument is a keyfile */
111 #endif
112 #ifdef ENABLE_CLI_LOCALTCPFWD
113 int nextislocal = 0;
114 #endif
115 #ifdef ENABLE_CLI_REMOTETCPFWD
116 int nextisremote = 0;
117 #endif
118 #ifdef ENABLE_CLI_NETCAT
119 int nextisnetcat = 0;
120 #endif
121 char* dummy = NULL; /* Not used for anything real */ 125 char* dummy = NULL; /* Not used for anything real */
122 126
123 char* recv_window_arg = NULL; 127 char* recv_window_arg = NULL;
124 char* keepalive_arg = NULL; 128 char* keepalive_arg = NULL;
125 char* idle_timeout_arg = NULL; 129 char* idle_timeout_arg = NULL;
126 char *host_arg = NULL; 130 char *host_arg = NULL;
131 char c;
127 132
128 /* see printhelp() for options */ 133 /* see printhelp() for options */
129 cli_opts.progname = argv[0]; 134 cli_opts.progname = argv[0];
130 cli_opts.remotehost = NULL; 135 cli_opts.remotehost = NULL;
131 cli_opts.remoteport = NULL; 136 cli_opts.remoteport = NULL;
170 opts.keepalive_secs = DEFAULT_KEEPALIVE; 175 opts.keepalive_secs = DEFAULT_KEEPALIVE;
171 opts.idle_timeout_secs = DEFAULT_IDLE_TIMEOUT; 176 opts.idle_timeout_secs = DEFAULT_IDLE_TIMEOUT;
172 177
173 fill_own_user(); 178 fill_own_user();
174 179
175 /* Iterate all the arguments */ 180 for (i = 1; i < (unsigned int)argc && argv[i][0] == '-'; i++) {
176 for (i = 1; i < (unsigned int)argc; i++) { 181 opt = OPT_OTHER;
177 #ifdef ENABLE_CLI_PUBKEY_AUTH 182 for (j = 1; (c = argv[i][j]) != '\0' && !next && opt == OPT_OTHER; j++) {
178 if (nextiskey) {
179 /* Load a hostkey since the previous argument was "-i" */
180 loadidentityfile(argv[i], 1);
181 nextiskey = 0;
182 continue;
183 }
184 #endif
185 #ifdef ENABLE_CLI_REMOTETCPFWD
186 if (nextisremote) {
187 TRACE(("nextisremote true"))
188 addforward(argv[i], cli_opts.remotefwds);
189 nextisremote = 0;
190 continue;
191 }
192 #endif
193 #ifdef ENABLE_CLI_LOCALTCPFWD
194 if (nextislocal) {
195 TRACE(("nextislocal true"))
196 addforward(argv[i], cli_opts.localfwds);
197 nextislocal = 0;
198 continue;
199 }
200 #endif
201 #ifdef ENABLE_CLI_NETCAT
202 if (nextisnetcat) {
203 TRACE(("nextisnetcat true"))
204 add_netcat(argv[i]);
205 nextisnetcat = 0;
206 continue;
207 }
208 #endif
209 if (next) {
210 /* The previous flag set a value to assign */
211 *next = argv[i];
212 if (*next == NULL) {
213 dropbear_exit("Invalid null argument");
214 }
215 next = NULL;
216 continue;
217 }
218
219 if (argv[i][0] == '-') {
220 /* A flag *waves* */
221 char c = argv[i][1];
222 if (strlen(argv[i]) != 2) {
223 /* We only handle one flag per hyphen */
224 fprintf(stderr, "Warning, trailing '%s' of '%s' is ignored.\n",
225 &argv[i][2], argv[i]);
226 }
227 switch (c) { 183 switch (c) {
228 case 'y': /* always accept the remote hostkey */ 184 case 'y': /* always accept the remote hostkey */
229 if (cli_opts.always_accept_key) { 185 if (cli_opts.always_accept_key) {
230 /* twice means no checking at all */ 186 /* twice means no checking at all */
231 cli_opts.no_hostkey_check = 1; 187 cli_opts.no_hostkey_check = 1;
235 case 'p': /* remoteport */ 191 case 'p': /* remoteport */
236 next = &cli_opts.remoteport; 192 next = &cli_opts.remoteport;
237 break; 193 break;
238 #ifdef ENABLE_CLI_PUBKEY_AUTH 194 #ifdef ENABLE_CLI_PUBKEY_AUTH
239 case 'i': /* an identityfile */ 195 case 'i': /* an identityfile */
240 /* Keep scp happy when it changes "-i file" to "-ifile" */ 196 opt = OPT_AUTHKEY;
241 if (strlen(argv[i]) > 2) {
242 loadidentityfile(&argv[i][2], 1);
243 } else {
244 nextiskey = 1;
245 }
246 break; 197 break;
247 #endif 198 #endif
248 case 't': /* we want a pty */ 199 case 't': /* we want a pty */
249 cli_opts.wantpty = 1; 200 cli_opts.wantpty = 1;
250 break; 201 break;
260 case 's': 211 case 's':
261 cli_opts.is_subsystem = 1; 212 cli_opts.is_subsystem = 1;
262 break; 213 break;
263 #ifdef ENABLE_CLI_LOCALTCPFWD 214 #ifdef ENABLE_CLI_LOCALTCPFWD
264 case 'L': 215 case 'L':
265 nextislocal = 1; 216 opt = OPT_LOCALTCPFWD;
266 break; 217 break;
267 case 'g': 218 case 'g':
268 opts.listen_fwd_all = 1; 219 opts.listen_fwd_all = 1;
269 break; 220 break;
270 #endif 221 #endif
271 #ifdef ENABLE_CLI_REMOTETCPFWD 222 #ifdef ENABLE_CLI_REMOTETCPFWD
272 case 'R': 223 case 'R':
273 nextisremote = 1; 224 opt = OPT_REMOTETCPFWD;
274 break; 225 break;
275 #endif 226 #endif
276 #ifdef ENABLE_CLI_NETCAT 227 #ifdef ENABLE_CLI_NETCAT
277 case 'B': 228 case 'B':
278 nextisnetcat = 1; 229 opt = OPT_NETCAT;
279 break; 230 break;
280 #endif 231 #endif
281 #ifdef ENABLE_CLI_PROXYCMD 232 #ifdef ENABLE_CLI_PROXYCMD
282 case 'J': 233 case 'J':
283 next = &cli_opts.proxycmd; 234 next = &cli_opts.proxycmd;
339 break; 290 break;
340 case 'o': 291 case 'o':
341 case 'b': 292 case 'b':
342 next = &dummy; 293 next = &dummy;
343 default: 294 default:
344 fprintf(stderr, 295 fprintf(stderr,
345 "WARNING: Ignoring unknown argument '%s'\n", argv[i]); 296 "WARNING: Ignoring unknown option -%c\n", c);
346 break; 297 break;
347 } /* Switch */ 298 } /* Switch */
348 299 }
349 /* Now we handle args where they might be "-luser" (no spaces)*/ 300
350 if (next && strlen(argv[i]) > 2) { 301 if (!next && opt == OPT_OTHER) /* got a flag */
351 *next = &argv[i][2]; 302 continue;
352 next = NULL; 303
353 } 304 if (c == '\0') {
354 305 i++;
355 continue; /* next argument */ 306 j = 0;
356 307 if (!argv[i])
357 } else { 308 dropbear_exit("Missing argument");
358 TRACE(("non-flag arg: '%s'", argv[i])) 309 }
359 310
360 /* Either the hostname or commands */ 311 #ifdef ENABLE_CLI_PUBKEY_AUTH
361 312 if (opt == OPT_AUTHKEY) {
362 if (host_arg == NULL) { 313 TRACE(("opt authkey"))
363 host_arg = argv[i]; 314 loadidentityfile(&argv[i][j], 1);
364 } else { 315 }
365 316 else
366 /* this is part of the commands to send - after this we 317 #endif
367 * don't parse any more options, and flags are sent as the 318 #ifdef ENABLE_CLI_REMOTETCPFWD
368 * command */ 319 if (opt == OPT_REMOTETCPFWD) {
369 cmdlen = 0; 320 TRACE(("opt remotetcpfwd"))
370 for (j = i; j < (unsigned int)argc; j++) { 321 addforward(&argv[i][j], cli_opts.remotefwds);
371 cmdlen += strlen(argv[j]) + 1; /* +1 for spaces */ 322 }
372 } 323 else
373 /* Allocate the space */ 324 #endif
374 cli_opts.cmd = (char*)m_malloc(cmdlen); 325 #ifdef ENABLE_CLI_LOCALTCPFWD
375 cli_opts.cmd[0] = '\0'; 326 if (opt == OPT_LOCALTCPFWD) {
376 327 TRACE(("opt localtcpfwd"))
377 /* Append all the bits */ 328 addforward(&argv[i][j], cli_opts.localfwds);
378 for (j = i; j < (unsigned int)argc; j++) { 329 }
379 strlcat(cli_opts.cmd, argv[j], cmdlen); 330 else
380 strlcat(cli_opts.cmd, " ", cmdlen); 331 #endif
381 } 332 #ifdef ENABLE_CLI_NETCAT
382 /* It'll be null-terminated here */ 333 if (opt == OPT_NETCAT) {
383 334 TRACE(("opt netcat"))
384 /* We've eaten all the options and flags */ 335 add_netcat(&argv[i][j]);
385 break; 336 }
386 } 337 else
387 } 338 #endif
339 if (next) {
340 /* The previous flag set a value to assign */
341 *next = &argv[i][j];
342 if (*next == NULL)
343 dropbear_exit("Invalid null argument");
344 next = NULL;
345 }
346 }
347
348 /* Done with options/flags; now handle the hostname (which may not
349 * start with a hyphen) and optional command */
350
351 if (i >= (unsigned int)argc) { /* missing hostname */
352 printhelp();
353 exit(EXIT_FAILURE);
354 }
355 host_arg = argv[i++];
356 TRACE(("host is: %s", host_arg))
357
358 if (i < (unsigned int)argc) {
359 /* Build the command to send */
360 cmdlen = 0;
361 for (j = i; j < (unsigned int)argc; j++)
362 cmdlen += strlen(argv[j]) + 1; /* +1 for spaces */
363
364 /* Allocate the space */
365 cli_opts.cmd = (char*)m_malloc(cmdlen);
366 cli_opts.cmd[0] = '\0';
367
368 /* Append all the bits */
369 for (j = i; j < (unsigned int)argc; j++) {
370 strlcat(cli_opts.cmd, argv[j], cmdlen);
371 strlcat(cli_opts.cmd, " ", cmdlen);
372 }
373 /* It'll be null-terminated here */
374 TRACE(("cmd is: %s", cli_opts.cmd))
388 } 375 }
389 376
390 /* And now a few sanity checks and setup */ 377 /* And now a few sanity checks and setup */
391 378
392 #ifdef ENABLE_USER_ALGO_LIST 379 #ifdef ENABLE_USER_ALGO_LIST
393 parse_ciphers_macs(); 380 parse_ciphers_macs();
394 #endif 381 #endif
395
396 if (host_arg == NULL) {
397 printhelp();
398 exit(EXIT_FAILURE);
399 }
400 382
401 #ifdef ENABLE_CLI_PROXYCMD 383 #ifdef ENABLE_CLI_PROXYCMD
402 if (cli_opts.proxycmd) { 384 if (cli_opts.proxycmd) {
403 /* To match the common path of m_freeing it */ 385 /* To match the common path of m_freeing it */
404 cli_opts.proxycmd = m_strdup(cli_opts.proxycmd); 386 cli_opts.proxycmd = m_strdup(cli_opts.proxycmd);