Код: Выделить всё
/* this method is envoked, if the server requires authentication */
static int ne_set_server_auth_callback(
void *userdata, const char *realm,
int attempt, char *username, char *password)
{
const size_t length = 100;
char buffer[length];
/* ask the user for the username and password if needed */
if (auth_data.username == NULL) {
printf("username: ");
if (fgets(buffer, length, stdin)) {
int len = strlen(buffer);
if (buffer[len - 1] == '\n')
buffer[len - 1] = '\0';
auth_data.username = strdup(buffer);
}
}
if (auth_data.password == NULL) {
printf("password: ");
if (fgets_hidden(buffer, length, stdin)) {
int len = strlen(buffer);
if (buffer[len - 1] == '\n')
buffer[len - 1] = '\0';
auth_data.password = strdup(buffer);
}
printf("\n");
}
assert(auth_data.username && auth_data.password);
strncpy(username, auth_data.username, NE_ABUFSIZ);
strncpy(password, auth_data.password, NE_ABUFSIZ);
return attempt;
}
По стандартам Си приглашения "username: " и "password: " не должны появляться до ввода данных пользователем без вызова fflush(stdout), но в силу нестандартности glibc, они появляются, как было задумано авторами. А в musl все стандартно и баг авторов виден невооруженным взглядом.
Следующий webdav-клиент с багами - cadaver. Там такой же глюк есть, если собирать без libreadline с musl. Но это мелочи. Как вам такой код (https://github.com/jmesmon/cadaver/blob ... commands.c):
Код: Выделить всё
/* Using a hack, we get zero-effort multiple-argument 'lls' */
static void execute_lls(int argc, const char **argv)
{
/* nasty cast; but these describe the same array of pointers, just
* with different constness, so it should be okay. */
char *const *vpargs = (char *const *)argv;
int pid;
pid = fork();
switch (pid) {
case 0: /* child... */
execvp("ls", &vpargs[-1]);
printf(_("Error executing ls: %s\n"), strerror(errno));
exit(-1);
break;
case -1: /* Error */
printf(_("Error forking ls: %s\n"), strerror(errno));
break;
default: /* Parent */
wait(NULL);
break;
}
return;
}
В результате имеем (включая Entware):
Код: Выделить всё
dav:/> lls
lls: applet not found
dav:/>
В общем, чтобы работало, нужно, чтобы ls был бинарем, а не симлинком на busybox или coreutils. Правильно должно быть так, видимо:
Код: Выделить всё
/* Using a hack, we get zero-effort multiple-argument 'lls' */
static void execute_lls(int argc, const char **argv)
{
/* nasty cast; but these describe the same array of pointers, just
* with different constness, so it should be okay. */
char *const *vpargs = NULL;
int pid;
pid = fork();
switch (pid) {
case 0: /* child... */
argv[-1]="ls";
vpargs=(char *const *)argv;
execvp("ls", &vpargs[-1]);
printf(_("Error executing ls: %s\n"), strerror(errno));
exit(-1);
break;
case -1: /* Error */
printf(_("Error forking ls: %s\n"), strerror(errno));
break;
default: /* Parent */
wait(NULL);
break;
}
return;
}
В родителе argv лучше не трогать, во избежание рантайм-ошибки.