cmdline.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. /*
  2. * cmdline.c - command-line parsing shared between many of the
  3. * PuTTY applications
  4. */
  5. #include <stdio.h>
  6. #include <assert.h>
  7. #include <stdlib.h>
  8. #include "putty.h"
  9. /*
  10. * Some command-line parameters need to be saved up until after
  11. * we've loaded the saved session which will form the basis of our
  12. * eventual running configuration. For this we use the macro
  13. * SAVEABLE, which notices if the `need_save' parameter is set and
  14. * saves the parameter and value on a list.
  15. *
  16. * We also assign priorities to saved parameters, just to slightly
  17. * ameliorate silly ordering problems. For example, if you specify
  18. * a saved session to load, it will be loaded _before_ all your
  19. * local modifications such as -L are evaluated; and if you specify
  20. * a protocol and a port, the protocol is set up first so that the
  21. * port can override its choice of port number.
  22. *
  23. * (In fact -load is not saved at all, since in at least Plink the
  24. * processing of further command-line options depends on whether or
  25. * not the loaded session contained a hostname. So it must be
  26. * executed immediately.)
  27. */
  28. #define NPRIORITIES 2
  29. struct cmdline_saved_param {
  30. char *p, *value;
  31. };
  32. struct cmdline_saved_param_set {
  33. struct cmdline_saved_param *params;
  34. int nsaved, savesize;
  35. };
  36. /*
  37. * C guarantees this structure will be initialised to all zero at
  38. * program start, which is exactly what we want.
  39. */
  40. static struct cmdline_saved_param_set saves[NPRIORITIES];
  41. static void cmdline_save_param(const char *p, const char *value, int pri)
  42. {
  43. if (saves[pri].nsaved >= saves[pri].savesize) {
  44. saves[pri].savesize = saves[pri].nsaved + 32;
  45. saves[pri].params = sresize(saves[pri].params, saves[pri].savesize,
  46. struct cmdline_saved_param);
  47. }
  48. saves[pri].params[saves[pri].nsaved].p = dupstr(p);
  49. saves[pri].params[saves[pri].nsaved].value = dupstr(value);
  50. saves[pri].nsaved++;
  51. }
  52. static char *cmdline_password = NULL;
  53. void cmdline_cleanup(void)
  54. {
  55. int pri;
  56. if (cmdline_password) {
  57. smemclr(cmdline_password, strlen(cmdline_password));
  58. sfree(cmdline_password);
  59. cmdline_password = NULL;
  60. }
  61. for (pri = 0; pri < NPRIORITIES; pri++) {
  62. sfree(saves[pri].params);
  63. saves[pri].params = NULL;
  64. saves[pri].savesize = 0;
  65. saves[pri].nsaved = 0;
  66. }
  67. }
  68. #define SAVEABLE(pri) do { \
  69. if (need_save) { cmdline_save_param(p, value, pri); return ret; } \
  70. } while (0)
  71. /*
  72. * Similar interface to get_userpass_input(), except that here a -1
  73. * return means that we aren't capable of processing the prompt and
  74. * someone else should do it.
  75. */
  76. int cmdline_get_passwd_input(prompts_t *p, const unsigned char *in, int inlen)
  77. {
  78. static int tried_once = 0;
  79. /*
  80. * We only handle prompts which don't echo (which we assume to be
  81. * passwords), and (currently) we only cope with a password prompt
  82. * that comes in a prompt-set on its own.
  83. */
  84. if (!cmdline_password || in || p->n_prompts != 1 || p->prompts[0]->echo) {
  85. return -1;
  86. }
  87. /*
  88. * If we've tried once, return utter failure (no more passwords left
  89. * to try).
  90. */
  91. if (tried_once)
  92. return 0;
  93. prompt_set_result(p->prompts[0], cmdline_password);
  94. smemclr(cmdline_password, strlen(cmdline_password));
  95. sfree(cmdline_password);
  96. cmdline_password = NULL;
  97. tried_once = 1;
  98. return 1;
  99. }
  100. /*
  101. * Here we have a flags word which describes the capabilities of
  102. * the particular tool on whose behalf we're running. We will
  103. * refuse certain command-line options if a particular tool
  104. * inherently can't do anything sensible. For example, the file
  105. * transfer tools (psftp, pscp) can't do a great deal with protocol
  106. * selections (ever tried running scp over telnet?) or with port
  107. * forwarding (even if it wasn't a hideously bad idea, they don't
  108. * have the select() infrastructure to make them work).
  109. */
  110. int cmdline_tooltype = 0;
  111. static int cmdline_check_unavailable(int flag, const char *p)
  112. {
  113. if (cmdline_tooltype & flag) {
  114. cmdline_error("option \"%s\" not available in this tool", p);
  115. return 1;
  116. }
  117. return 0;
  118. }
  119. #define UNAVAILABLE_IN(flag) do { \
  120. if (cmdline_check_unavailable(flag, p)) return ret; \
  121. } while (0)
  122. /*
  123. * Process a standard command-line parameter. `p' is the parameter
  124. * in question; `value' is the subsequent element of argv, which
  125. * may or may not be required as an operand to the parameter.
  126. * If `need_save' is 1, arguments which need to be saved as
  127. * described at this top of this file are, for later execution;
  128. * if 0, they are processed normally. (-1 is a special value used
  129. * by pterm to count arguments for a preliminary pass through the
  130. * argument list; it causes immediate return with an appropriate
  131. * value with no action taken.)
  132. * Return value is 2 if both arguments were used; 1 if only p was
  133. * used; 0 if the parameter wasn't one we recognised; -2 if it
  134. * should have been 2 but value was NULL.
  135. */
  136. #define RETURN(x) do { \
  137. if ((x) == 2 && !value) return -2; \
  138. ret = x; \
  139. if (need_save < 0) return x; \
  140. } while (0)
  141. int cmdline_process_param(const char *p, char *value,
  142. int need_save, Conf *conf)
  143. {
  144. int ret = 0;
  145. if (!strcmp(p, "-load")) {
  146. RETURN(2);
  147. /* This parameter must be processed immediately rather than being
  148. * saved. */
  149. do_defaults(value, conf);
  150. loaded_session = TRUE;
  151. cmdline_session_name = dupstr(value);
  152. return 2;
  153. }
  154. if (!strcmp(p, "-ssh")) {
  155. RETURN(1);
  156. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  157. SAVEABLE(0);
  158. default_protocol = PROT_SSH;
  159. default_port = 22;
  160. conf_set_int(conf, CONF_protocol, default_protocol);
  161. conf_set_int(conf, CONF_port, default_port);
  162. return 1;
  163. }
  164. if (!strcmp(p, "-telnet")) {
  165. RETURN(1);
  166. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  167. SAVEABLE(0);
  168. default_protocol = PROT_TELNET;
  169. default_port = 23;
  170. conf_set_int(conf, CONF_protocol, default_protocol);
  171. conf_set_int(conf, CONF_port, default_port);
  172. return 1;
  173. }
  174. if (!strcmp(p, "-rlogin")) {
  175. RETURN(1);
  176. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  177. SAVEABLE(0);
  178. default_protocol = PROT_RLOGIN;
  179. default_port = 513;
  180. conf_set_int(conf, CONF_protocol, default_protocol);
  181. conf_set_int(conf, CONF_port, default_port);
  182. return 1;
  183. }
  184. if (!strcmp(p, "-raw")) {
  185. RETURN(1);
  186. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  187. SAVEABLE(0);
  188. default_protocol = PROT_RAW;
  189. conf_set_int(conf, CONF_protocol, default_protocol);
  190. }
  191. if (!strcmp(p, "-serial")) {
  192. RETURN(1);
  193. /* Serial is not NONNETWORK in an odd sense of the word */
  194. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  195. SAVEABLE(0);
  196. default_protocol = PROT_SERIAL;
  197. conf_set_int(conf, CONF_protocol, default_protocol);
  198. /* The host parameter will already be loaded into CONF_host,
  199. * so copy it across */
  200. conf_set_str(conf, CONF_serline, conf_get_str(conf, CONF_host));
  201. }
  202. if (!strcmp(p, "-v")) {
  203. RETURN(1);
  204. flags |= FLAG_VERBOSE;
  205. }
  206. if (!strcmp(p, "-l")) {
  207. RETURN(2);
  208. UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
  209. SAVEABLE(0);
  210. conf_set_str(conf, CONF_username, value);
  211. }
  212. if (!strcmp(p, "-loghost")) {
  213. RETURN(2);
  214. UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
  215. SAVEABLE(0);
  216. conf_set_str(conf, CONF_loghost, value);
  217. }
  218. if (!strcmp(p, "-hostkey")) {
  219. char *dup;
  220. RETURN(2);
  221. UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
  222. SAVEABLE(0);
  223. dup = dupstr(value);
  224. if (!validate_manual_hostkey(dup)) {
  225. cmdline_error("'%s' is not a valid format for a manual host "
  226. "key specification", value);
  227. sfree(dup);
  228. return ret;
  229. }
  230. conf_set_str_str(conf, CONF_ssh_manual_hostkeys, dup, "");
  231. sfree(dup);
  232. }
  233. if ((!strcmp(p, "-L") || !strcmp(p, "-R") || !strcmp(p, "-D"))) {
  234. char type, *q, *qq, *key, *val;
  235. RETURN(2);
  236. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  237. SAVEABLE(0);
  238. if (strcmp(p, "-D")) {
  239. /*
  240. * For -L or -R forwarding types:
  241. *
  242. * We expect _at least_ two colons in this string. The
  243. * possible formats are `sourceport:desthost:destport',
  244. * or `sourceip:sourceport:desthost:destport' if you're
  245. * specifying a particular loopback address. We need to
  246. * replace the one between source and dest with a \t;
  247. * this means we must find the second-to-last colon in
  248. * the string.
  249. *
  250. * (This looks like a foolish way of doing it given the
  251. * existence of strrchr, but it's more efficient than
  252. * two strrchrs - not to mention that the second strrchr
  253. * would require us to modify the input string!)
  254. */
  255. type = p[1]; /* 'L' or 'R' */
  256. q = qq = host_strchr(value, ':');
  257. while (qq) {
  258. char *qqq = host_strchr(qq+1, ':');
  259. if (qqq)
  260. q = qq;
  261. qq = qqq;
  262. }
  263. if (!q) {
  264. cmdline_error("-%c expects at least two colons in its"
  265. " argument", type);
  266. return ret;
  267. }
  268. key = dupprintf("%c%.*s", type, (int)(q - value), value);
  269. val = dupstr(q+1);
  270. } else {
  271. /*
  272. * Dynamic port forwardings are entered under the same key
  273. * as if they were local (because they occupy the same
  274. * port space - a local and a dynamic forwarding on the
  275. * same local port are mutually exclusive), with the
  276. * special value "D" (which can be distinguished from
  277. * anything in the ordinary -L case by containing no
  278. * colon).
  279. */
  280. key = dupprintf("L%s", value);
  281. val = dupstr("D");
  282. }
  283. conf_set_str_str(conf, CONF_portfwd, key, val);
  284. sfree(key);
  285. sfree(val);
  286. }
  287. if ((!strcmp(p, "-nc"))) {
  288. char *host, *portp;
  289. RETURN(2);
  290. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  291. SAVEABLE(0);
  292. portp = host_strchr(value, ':');
  293. if (!portp) {
  294. cmdline_error("-nc expects argument of form 'host:port'");
  295. return ret;
  296. }
  297. host = dupprintf("%.*s", (int)(portp - value), value);
  298. conf_set_str(conf, CONF_ssh_nc_host, host);
  299. conf_set_int(conf, CONF_ssh_nc_port, atoi(portp + 1));
  300. sfree(host);
  301. }
  302. if (!strcmp(p, "-m")) {
  303. const char *filename;
  304. char *command;
  305. int cmdlen, cmdsize;
  306. FILE *fp;
  307. int c, d;
  308. RETURN(2);
  309. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  310. SAVEABLE(0);
  311. filename = value;
  312. cmdlen = cmdsize = 0;
  313. command = NULL;
  314. fp = fopen(filename, "r");
  315. if (!fp) {
  316. cmdline_error("unable to open command file \"%s\"", filename);
  317. return ret;
  318. }
  319. do {
  320. c = fgetc(fp);
  321. d = c;
  322. if (c == EOF)
  323. d = 0;
  324. if (cmdlen >= cmdsize) {
  325. cmdsize = cmdlen + 512;
  326. command = sresize(command, cmdsize, char);
  327. }
  328. command[cmdlen++] = d;
  329. } while (c != EOF);
  330. fclose(fp);
  331. conf_set_str(conf, CONF_remote_cmd, command);
  332. conf_set_str(conf, CONF_remote_cmd2, "");
  333. conf_set_int(conf, CONF_nopty, TRUE); /* command => no terminal */
  334. sfree(command);
  335. }
  336. if (!strcmp(p, "-P")) {
  337. RETURN(2);
  338. UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
  339. SAVEABLE(1); /* lower priority than -ssh,-telnet */
  340. conf_set_int(conf, CONF_port, atoi(value));
  341. }
  342. if (!strcmp(p, "-pw")) {
  343. RETURN(2);
  344. UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
  345. SAVEABLE(1);
  346. /* We delay evaluating this until after the protocol is decided,
  347. * so that we can warn if it's of no use with the selected protocol */
  348. if (conf_get_int(conf, CONF_protocol) != PROT_SSH)
  349. cmdline_error("the -pw option can only be used with the "
  350. "SSH protocol");
  351. else {
  352. cmdline_password = dupstr(value);
  353. /* Assuming that `value' is directly from argv, make a good faith
  354. * attempt to trample it, to stop it showing up in `ps' output
  355. * on Unix-like systems. Not guaranteed, of course. */
  356. smemclr(value, strlen(value));
  357. }
  358. }
  359. if (!strcmp(p, "-agent") || !strcmp(p, "-pagent") ||
  360. !strcmp(p, "-pageant")) {
  361. RETURN(1);
  362. UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
  363. SAVEABLE(0);
  364. conf_set_int(conf, CONF_tryagent, TRUE);
  365. }
  366. if (!strcmp(p, "-noagent") || !strcmp(p, "-nopagent") ||
  367. !strcmp(p, "-nopageant")) {
  368. RETURN(1);
  369. UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
  370. SAVEABLE(0);
  371. conf_set_int(conf, CONF_tryagent, FALSE);
  372. }
  373. if (!strcmp(p, "-A")) {
  374. RETURN(1);
  375. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  376. SAVEABLE(0);
  377. conf_set_int(conf, CONF_agentfwd, 1);
  378. }
  379. if (!strcmp(p, "-a")) {
  380. RETURN(1);
  381. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  382. SAVEABLE(0);
  383. conf_set_int(conf, CONF_agentfwd, 0);
  384. }
  385. if (!strcmp(p, "-X")) {
  386. RETURN(1);
  387. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  388. SAVEABLE(0);
  389. conf_set_int(conf, CONF_x11_forward, 1);
  390. }
  391. if (!strcmp(p, "-x")) {
  392. RETURN(1);
  393. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  394. SAVEABLE(0);
  395. conf_set_int(conf, CONF_x11_forward, 0);
  396. }
  397. if (!strcmp(p, "-t")) {
  398. RETURN(1);
  399. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  400. SAVEABLE(1); /* lower priority than -m */
  401. conf_set_int(conf, CONF_nopty, 0);
  402. }
  403. if (!strcmp(p, "-T")) {
  404. RETURN(1);
  405. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  406. SAVEABLE(1);
  407. conf_set_int(conf, CONF_nopty, 1);
  408. }
  409. if (!strcmp(p, "-N")) {
  410. RETURN(1);
  411. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  412. SAVEABLE(0);
  413. conf_set_int(conf, CONF_ssh_no_shell, 1);
  414. }
  415. if (!strcmp(p, "-C")) {
  416. RETURN(1);
  417. UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
  418. SAVEABLE(0);
  419. conf_set_int(conf, CONF_compression, 1);
  420. }
  421. if (!strcmp(p, "-1")) {
  422. RETURN(1);
  423. UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
  424. SAVEABLE(0);
  425. conf_set_int(conf, CONF_sshprot, 0); /* ssh protocol 1 only */
  426. }
  427. if (!strcmp(p, "-2")) {
  428. RETURN(1);
  429. UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
  430. SAVEABLE(0);
  431. conf_set_int(conf, CONF_sshprot, 3); /* ssh protocol 2 only */
  432. }
  433. if (!strcmp(p, "-i")) {
  434. Filename *fn;
  435. RETURN(2);
  436. UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
  437. SAVEABLE(0);
  438. fn = filename_from_str(value);
  439. conf_set_filename(conf, CONF_keyfile, fn);
  440. filename_free(fn);
  441. }
  442. if (!strcmp(p, "-4") || !strcmp(p, "-ipv4")) {
  443. RETURN(1);
  444. SAVEABLE(1);
  445. conf_set_int(conf, CONF_addressfamily, ADDRTYPE_IPV4);
  446. }
  447. if (!strcmp(p, "-6") || !strcmp(p, "-ipv6")) {
  448. RETURN(1);
  449. SAVEABLE(1);
  450. conf_set_int(conf, CONF_addressfamily, ADDRTYPE_IPV6);
  451. }
  452. if (!strcmp(p, "-sercfg")) {
  453. char* nextitem;
  454. RETURN(2);
  455. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
  456. SAVEABLE(1);
  457. if (conf_get_int(conf, CONF_protocol) != PROT_SERIAL)
  458. cmdline_error("the -sercfg option can only be used with the "
  459. "serial protocol");
  460. /* Value[0] contains one or more , separated values, like 19200,8,n,1,X */
  461. nextitem = value;
  462. while (nextitem[0] != '\0') {
  463. int length, skip;
  464. char *end = strchr(nextitem, ',');
  465. if (!end) {
  466. length = strlen(nextitem);
  467. skip = 0;
  468. } else {
  469. length = end - nextitem;
  470. nextitem[length] = '\0';
  471. skip = 1;
  472. }
  473. if (length == 1) {
  474. switch (*nextitem) {
  475. case '1':
  476. case '2':
  477. conf_set_int(conf, CONF_serstopbits, 2 * (*nextitem-'0'));
  478. break;
  479. case '5':
  480. case '6':
  481. case '7':
  482. case '8':
  483. case '9':
  484. conf_set_int(conf, CONF_serdatabits, *nextitem-'0');
  485. break;
  486. case 'n':
  487. conf_set_int(conf, CONF_serparity, SER_PAR_NONE);
  488. break;
  489. case 'o':
  490. conf_set_int(conf, CONF_serparity, SER_PAR_ODD);
  491. break;
  492. case 'e':
  493. conf_set_int(conf, CONF_serparity, SER_PAR_EVEN);
  494. break;
  495. case 'm':
  496. conf_set_int(conf, CONF_serparity, SER_PAR_MARK);
  497. break;
  498. case 's':
  499. conf_set_int(conf, CONF_serparity, SER_PAR_SPACE);
  500. break;
  501. case 'N':
  502. conf_set_int(conf, CONF_serflow, SER_FLOW_NONE);
  503. break;
  504. case 'X':
  505. conf_set_int(conf, CONF_serflow, SER_FLOW_XONXOFF);
  506. break;
  507. case 'R':
  508. conf_set_int(conf, CONF_serflow, SER_FLOW_RTSCTS);
  509. break;
  510. case 'D':
  511. conf_set_int(conf, CONF_serflow, SER_FLOW_DSRDTR);
  512. break;
  513. default:
  514. cmdline_error("Unrecognised suboption \"-sercfg %c\"",
  515. *nextitem);
  516. }
  517. } else if (length == 3 && !strncmp(nextitem,"1.5",3)) {
  518. /* Messy special case */
  519. conf_set_int(conf, CONF_serstopbits, 3);
  520. } else {
  521. int serspeed = atoi(nextitem);
  522. if (serspeed != 0) {
  523. conf_set_int(conf, CONF_serspeed, serspeed);
  524. } else {
  525. cmdline_error("Unrecognised suboption \"-sercfg %s\"",
  526. nextitem);
  527. }
  528. }
  529. nextitem += length + skip;
  530. }
  531. }
  532. if (!strcmp(p, "-sessionlog")) {
  533. Filename *fn;
  534. RETURN(2);
  535. UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER);
  536. /* but available even in TOOLTYPE_NONNETWORK, cf pterm "-log" */
  537. SAVEABLE(0);
  538. fn = filename_from_str(value);
  539. conf_set_filename(conf, CONF_logfilename, fn);
  540. conf_set_int(conf, CONF_logtype, LGTYP_DEBUG);
  541. filename_free(fn);
  542. }
  543. if (!strcmp(p, "-sshlog") ||
  544. !strcmp(p, "-sshrawlog")) {
  545. Filename *fn;
  546. RETURN(2);
  547. UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
  548. SAVEABLE(0);
  549. fn = filename_from_str(value);
  550. conf_set_filename(conf, CONF_logfilename, fn);
  551. conf_set_int(conf, CONF_logtype,
  552. !strcmp(p, "-sshlog") ? LGTYP_PACKETS :
  553. /* !strcmp(p, "-sshrawlog") ? */ LGTYP_SSHRAW);
  554. filename_free(fn);
  555. }
  556. return ret; /* unrecognised */
  557. }
  558. void cmdline_run_saved(Conf *conf)
  559. {
  560. int pri, i;
  561. for (pri = 0; pri < NPRIORITIES; pri++) {
  562. for (i = 0; i < saves[pri].nsaved; i++) {
  563. cmdline_process_param(saves[pri].params[i].p,
  564. saves[pri].params[i].value, 0, conf);
  565. sfree(saves[pri].params[i].p);
  566. sfree(saves[pri].params[i].value);
  567. }
  568. saves[pri].nsaved = 0;
  569. }
  570. }