Webdav клиенты

Используем пакеты, расширяющие возможности оборудования
kaztost
Сообщения: 223
Зарегистрирован: 16 июл 2017, 23:29

Сообщение kaztost » 21 апр 2019, 18:56

Замечательный пример "гомнокода" wdfs https://github.com/jmesmon/wdfs/blob/ma ... c/webdav.c

Код: Выделить всё

/* 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 лучше не трогать, во избежание рантайм-ошибки.

Аватара пользователя
Александр Рыжов
Сообщения: 397
Зарегистрирован: 12 авг 2015, 13:14
Откуда: Смоленск

Сообщение Александр Рыжов » 21 апр 2019, 19:52

Оба-два брошены 10 лет назад. Держим их исключительно из-за легковесности по сравнению с davfs2.


Вернуться в «Entware/Qnapware/Optware/Zyxware - обсуждаем репозитории пакетов»

Кто сейчас на конференции

Всего 2 посетителя :: 0 зарегистрированных, 0 скрытых и 2 гостя (основано на активности пользователей за последние 5 минут)
Больше всего посетителей (121) здесь было 18 май 2016, 18:19

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя