- UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER);
- SAVEABLE(1);
- fwd = value;
- ptr = cfg->portfwd;
- /* if multiple forwards, find end of list */
- if (ptr[0]=='R' || ptr[0]=='L') {
- for (i = 0; i < sizeof(cfg->portfwd) - 2; i++)
- if (ptr[i]=='\000' && ptr[i+1]=='\000')
- break;
- ptr = ptr + i + 1; /* point to next forward slot */
+ UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
+ SAVEABLE(0);
+ conf_set_str(conf, CONF_loghost, value);
+ }
+ if ((!strcmp(p, "-L") || !strcmp(p, "-R") || !strcmp(p, "-D"))) {
+ char type, *q, *qq, *key, *val;
+ RETURN(2);
+ UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
+ SAVEABLE(0);
+ if (strcmp(p, "-D")) {
+ /*
+ * For -L or -R forwarding types:
+ *
+ * We expect _at least_ two colons in this string. The
+ * possible formats are `sourceport:desthost:destport',
+ * or `sourceip:sourceport:desthost:destport' if you're
+ * specifying a particular loopback address. We need to
+ * replace the one between source and dest with a \t;
+ * this means we must find the second-to-last colon in
+ * the string.
+ *
+ * (This looks like a foolish way of doing it given the
+ * existence of strrchr, but it's more efficient than
+ * two strrchrs - not to mention that the second strrchr
+ * would require us to modify the input string!)
+ */
+
+ type = p[1]; /* 'L' or 'R' */
+
+ q = qq = strchr(value, ':');
+ while (qq) {
+ char *qqq = strchr(qq+1, ':');
+ if (qqq)
+ q = qq;
+ qq = qqq;
+ }
+
+ if (!q) {
+ cmdline_error("-%c expects at least two colons in its"
+ " argument", type);
+ return ret;
+ }
+
+ key = dupprintf("%c%.*s", type, q - value, value);
+ val = dupstr(q+1);
+ } else {
+ /*
+ * Dynamic port forwardings are entered under the same key
+ * as if they were local (because they occupy the same
+ * port space - a local and a dynamic forwarding on the
+ * same local port are mutually exclusive), with the
+ * special value "D" (which can be distinguished from
+ * anything in the ordinary -L case by containing no
+ * colon).
+ */
+ key = dupprintf("L%s", value);
+ val = dupstr("D");