This routine is always called with a tmpbuf of MAX_NSTR_STRLEN length, but the * buffer may be pre-populated with a "len" length string to use OR a len of -1 * to tell us to read a string from the fd. */
| 367 | * buffer may be pre-populated with a "len" length string to use OR a len of -1 |
| 368 | * to tell us to read a string from the fd. */ |
| 369 | static void recv_negotiate_str(int f_in, struct name_num_obj *nno, char *tmpbuf, int len) |
| 370 | { |
| 371 | if (len < 0) |
| 372 | len = read_vstring(f_in, tmpbuf, MAX_NSTR_STRLEN); |
| 373 | |
| 374 | if (DEBUG_GTE(NSTR, am_server ? 3 : 2)) { |
| 375 | if (am_server) |
| 376 | rprintf(FINFO, "Client %s list (on server): %s\n", nno->type, tmpbuf); |
| 377 | else |
| 378 | rprintf(FINFO, "Server %s list (on client): %s\n", nno->type, tmpbuf); |
| 379 | } |
| 380 | |
| 381 | if (len > 0 && parse_negotiate_str(nno, tmpbuf)) |
| 382 | return; |
| 383 | |
| 384 | if (!am_server || !do_negotiated_strings) { |
| 385 | char *cp = tmpbuf; |
| 386 | int j; |
| 387 | rprintf(FERROR, "Failed to negotiate a %s choice.\n", nno->type); |
| 388 | rprintf(FERROR, "%s list: %s\n", am_server ? "Client" : "Server", tmpbuf); |
| 389 | /* Recreate our original list from the saw values. This can't overflow our huge |
| 390 | * buffer because we don't have enough valid entries to get anywhere close. */ |
| 391 | for (j = 1, *cp = '\0'; j <= nno->saw_len; j++) { |
| 392 | struct name_num_item *nni; |
| 393 | for (nni = nno->list; nni->name; nni++) { |
| 394 | if (nno->saw[nni->num] == j) { |
| 395 | *cp++ = ' '; |
| 396 | cp += strlcpy(cp, nni->name, MAX_NSTR_STRLEN - (cp - tmpbuf)); |
| 397 | break; |
| 398 | } |
| 399 | } |
| 400 | } |
| 401 | if (!*tmpbuf) |
| 402 | strlcpy(cp, " INVALID", MAX_NSTR_STRLEN); |
| 403 | rprintf(FERROR, "%s list:%s\n", am_server ? "Server" : "Client", tmpbuf); |
| 404 | } |
| 405 | |
| 406 | exit_cleanup(RERR_UNSUPPORTED); |
| 407 | } |
| 408 | |
| 409 | static const char *getenv_nstr(int ntype) |
| 410 | { |
no test coverage detected