Esempio n. 1
0
static int filesystem_copy(const char *name, const char *destname)
{
	void *in, *out;
	ssize_t ret;
	size_t size;
	struct stat st;
	int in_fd, out_fd, err;

	in = filesystem_open(name, O_RDONLY, 0, NULL, &size, &err);
	if (in == NULL) {
		error("open(%s): %s (%d)", name, strerror(-err), -err);
		return -err;
	}

	in_fd = GPOINTER_TO_INT(in);
	ret = fstat(in_fd, &st);
	if (ret < 0) {
		error("stat(%s): %s (%d)", name, strerror(errno), errno);
		return -errno;
	}

	out = filesystem_open(destname, O_WRONLY | O_CREAT | O_TRUNC,
					st.st_mode, NULL, &size, &err);
	if (out == NULL) {
		error("open(%s): %s (%d)", destname, strerror(-err), -err);
		filesystem_close(in);
		return -errno;
	}

	out_fd = GPOINTER_TO_INT(out);

	/* Check if sendfile is supported */
	ret = sendfile(out_fd, in_fd, NULL, 0);
	if (ret < 0) {
		ret = -errno;
		error("sendfile: %s (%zd)", strerror(-ret), -ret);
		goto done;
	}

	ret = sendfile_async(out_fd, in_fd, NULL, st.st_size);
	if (ret < 0)
		goto done;

	return 0;

done:
	filesystem_close(in);
	filesystem_close(out);

	return ret;
}
Esempio n. 2
0
static void handle_filesystem_request(int so)
{
	int error;
	int operation;
	char key[(NAME_MAX + 1) + sizeof(union webdav_request)];
	size_t num_bytes;
	char *bytes;
	union webdav_reply reply;
	
	/* get the request from the socket */
	error = get_request(so, &operation, key, sizeof(key));
	if ( !error ) {
#if DEBUG	
		LogMessage(kTrace, "handle_filesystem_request: %s(%d)\n",
				(operation==WEBDAV_LOOKUP) ? "LOOKUP" :
				(operation==WEBDAV_CREATE) ? "CREATE" :
				(operation==WEBDAV_OPEN) ? "OPEN" :
				(operation==WEBDAV_CLOSE) ? "CLOSE" :
				(operation==WEBDAV_GETATTR) ? "GETATTR" :
				(operation==WEBDAV_SETATTR) ? "SETATTR" :
				(operation==WEBDAV_READ) ? "READ" :
				(operation==WEBDAV_WRITE) ? "WRITE" :
				(operation==WEBDAV_FSYNC) ? "FSYNC" :
				(operation==WEBDAV_REMOVE) ? "REMOVE" :
				(operation==WEBDAV_RENAME) ? "RENAME" :
				(operation==WEBDAV_MKDIR) ? "MKDIR" :
				(operation==WEBDAV_RMDIR) ? "RMDIR" :
				(operation==WEBDAV_READDIR) ? "READDIR" :
				(operation==WEBDAV_STATFS) ? "STATFS" :
				(operation==WEBDAV_UNMOUNT) ? "UNMOUNT" :
				(operation==WEBDAV_INVALCACHES) ? "INVALCACHES" :
				"???",
				operation
				);
#endif
		bzero((void *)&reply, sizeof(union webdav_reply));
		
		/* If the connection is down just return EBUSY, but always let UNMOUNT and INVALCACHES requests */
		/* go through regardless of the state of the connection. */
		if ( (get_connectionstate() == WEBDAV_CONNECTION_DOWN) && (operation != WEBDAV_UNMOUNT) &&
			(operation != WEBDAV_INVALCACHES) )
		{
			error = ETIMEDOUT;
			send_reply(so, (void *)&reply, sizeof(union webdav_reply), error);
		}
		else
		{
			/* call the function to handle the request */
			switch ( operation )
			{
				case WEBDAV_LOOKUP:
					error = filesystem_lookup((struct webdav_request_lookup *)key,
							(struct webdav_reply_lookup *)&reply);
					send_reply(so, (void *)&reply, sizeof(struct webdav_reply_lookup), error);
					break;

				case WEBDAV_CREATE:
					error = filesystem_create((struct webdav_request_create *)key,
							(struct webdav_reply_create *)&reply);
					send_reply(so, (void *)&reply, sizeof(struct webdav_reply_create), error);
					break;

				case WEBDAV_OPEN:
					error = filesystem_open((struct webdav_request_open *)key,
							(struct webdav_reply_open *)&reply);
					send_reply(so, (void *)&reply, sizeof(struct webdav_reply_open), error);
					break;

				case WEBDAV_CLOSE:
					error = filesystem_close((struct webdav_request_close *)key);				
					send_reply(so, (void *)0, 0, error);
					break;

				case WEBDAV_GETATTR:
					error = filesystem_getattr((struct webdav_request_getattr *)key,
							(struct webdav_reply_getattr *)&reply);
					send_reply(so, (void *)&reply, sizeof(struct webdav_reply_getattr), error);
					break;

				case WEBDAV_READ:
					bytes = NULL;
					num_bytes = 0;
					error = filesystem_read((struct webdav_request_read *)key,
							&bytes, &num_bytes);				
					send_reply(so, (void *)bytes, (int)num_bytes, error);
					if (bytes)
					{
						free(bytes);
					}
					break;

				case WEBDAV_FSYNC:
					error = filesystem_fsync((struct webdav_request_fsync *)key);			
					send_reply(so, (void *)0, 0, error);
					break;

				case WEBDAV_REMOVE:
					error = filesystem_remove((struct webdav_request_remove *)key);				
					send_reply(so, (void *)0, 0, error);
					break;

				case WEBDAV_RENAME:
					error = filesystem_rename((struct webdav_request_rename *)key);
					send_reply(so, (void *)0, 0, error);
					break;

				case WEBDAV_MKDIR:
					error = filesystem_mkdir((struct webdav_request_mkdir *)key,
							(struct webdav_reply_mkdir *)&reply);
					send_reply(so, (void *)&reply, sizeof(struct webdav_reply_mkdir), error);
					break;

				case WEBDAV_RMDIR:
					error = filesystem_rmdir((struct webdav_request_rmdir *)key);
					send_reply(so, (void *)0, 0, error);
					break;

				case WEBDAV_READDIR:
					error = filesystem_readdir((struct webdav_request_readdir *)key);
					send_reply(so, (void *)0, 0, error);
					break;

				case WEBDAV_STATFS:
					error = filesystem_statfs((struct webdav_request_statfs *)key,
							(struct webdav_reply_statfs *)&reply);
					send_reply(so, (void *)&reply, sizeof(struct webdav_reply_statfs), error);
					break;
			
				case WEBDAV_UNMOUNT:
					webdav_kill(-2);	/* tell the main select loop to exit */
					send_reply(so, (void *)0, 0, error);
					break;

				case WEBDAV_INVALCACHES:
					error = filesystem_invalidate_caches((struct webdav_request_invalcaches *)key);
					send_reply(so, (void *)0, 0, error);
					break;

				case WEBDAV_WRITESEQ:
					error = filesystem_write_seq((struct webdav_request_writeseq *)key);
					send_reply(so, (void *)0, 0, error);
					break;
					
				case WEBDAV_DUMP_COOKIES:
					dump_cookies((struct webdav_request_cookies *)key);
					send_reply(so, (void *)0, 0, error);
					break;
					
				case WEBDAV_CLEAR_COOKIES:
					reset_cookies((struct webdav_request_cookies *)key);
					send_reply(so, (void *)0, 0, error);
					break;
				
				default:
					error = ENOTSUP;
					break;
			}
		}

#if DEBUG
		LogMessage(kError, "handle_filesystem_request: error %d, %s(%d)\n", error,
					(operation==WEBDAV_LOOKUP) ? "LOOKUP" :
					(operation==WEBDAV_CREATE) ? "CREATE" :
					(operation==WEBDAV_OPEN) ? "OPEN" :
					(operation==WEBDAV_CLOSE) ? "CLOSE" :
					(operation==WEBDAV_GETATTR) ? "GETATTR" :
					(operation==WEBDAV_SETATTR) ? "SETATTR" :
					(operation==WEBDAV_READ) ? "READ" :
					(operation==WEBDAV_WRITE) ? "WRITE" :
					(operation==WEBDAV_FSYNC) ? "FSYNC" :
					(operation==WEBDAV_REMOVE) ? "REMOVE" :
					(operation==WEBDAV_RENAME) ? "RENAME" :
					(operation==WEBDAV_MKDIR) ? "MKDIR" :
					(operation==WEBDAV_RMDIR) ? "RMDIR" :
					(operation==WEBDAV_READDIR) ? "READDIR" :
					(operation==WEBDAV_STATFS) ? "STATFS" :
					(operation==WEBDAV_UNMOUNT) ? "UNMOUNT" :
					(operation==WEBDAV_INVALCACHES) ? "INVALCACHES" :
					"???",
					operation
					);
#endif
	}
	else {
		LogMessage(kError, "handle_filesystem_request: get_request failed %d\n", error);
		send_reply(so, NULL, 0, error);
	}

	close(so);
}