예제 #1
0
파일: webdav.c 프로젝트: hchtym/onion
/**
 * @short Deletes a resource
 */
onion_connection_status onion_webdav_delete(const char *filename, onion_webdav *wd, onion_request *req, onion_response *res){
	ONION_DEBUG("Webdav delete %s", filename);
	int error=remove(filename);
	if (error==0)
		return onion_shortcut_response("Deleted", HTTP_OK, req, res);
	else{
		ONION_ERROR("Could not remove WebDAV resource");
		return onion_shortcut_response("Could not delete resource", HTTP_INTERNAL_ERROR, req, res);
	}
}
예제 #2
0
/// Sets internally the window title, for reference.
int oterm_title(process *p, onion_request* req, onion_response *res){
	const char *t=onion_request_get_post(req, "title");
	
	if (!t)
		return onion_shortcut_response("Error, must set title", HTTP_INTERNAL_ERROR, req, res);
	
	if (p->title)
		free(p->title);
	p->title=strdup(t);
	
	ONION_DEBUG("Set term %d title %s", p->pid, p->title);
	
	return onion_shortcut_response("OK", HTTP_OK, req, res);
}
예제 #3
0
파일: webdav.c 프로젝트: hchtym/onion
/**
 * @short Moves a resource
 */
onion_connection_status onion_webdav_move(const char *filename, onion_webdav *wd, onion_request *req, onion_response *res){
	const char *dest=onion_request_get_header(req,"Destination");
	if (!dest)
		return OCS_INTERNAL_ERROR;
	const char *dest_orig=dest;
	// Skip the http... part. Just 3 /.
	int i;
	for (i=0;i<3;i+=(*dest++=='/'))
		if (*dest==0)
			return OCS_INTERNAL_ERROR;
	dest--;
	
	const char *fullpath=onion_request_get_fullpath(req);
	const char *partialpath=onion_request_get_path(req);
	// Not the fixed URL part for this handler.
	int fpl=strlen(fullpath); // Full path length
	int ppl=strlen(onion_request_get_path(req)); // Partial, the fullpath[fpl-ppl] is the end point of the handler path
	if (strncmp(fullpath, dest, fpl-ppl)!=0){
		char tmp[512];
		int l=fpl-ppl < sizeof(tmp)-1 ? fpl-ppl : sizeof(tmp)-1;
		strncpy(tmp, fullpath, l);
		tmp[l]=0;
		ONION_WARNING("Move to out of this webdav share! (%s is out of %s)", dest, tmp);
		return onion_shortcut_response("Moving out of shared share", HTTP_FORBIDDEN, req, res);
	}
	dest=&dest[fpl-ppl];


	char orig[512];
	snprintf(orig, sizeof(orig), "%s/%s", wd->path, partialpath);
	
	if (wd->check_permissions(wd->path, orig, req)!=0){
		return onion_shortcut_response("Forbidden", HTTP_FORBIDDEN, req, res);
	}

	const char *fdest=filename;

	ONION_INFO("Move %s to %s (webdav)", fullpath, dest_orig);
	
	int ok=onion_shortcut_rename(orig, fdest);

	if (ok==0){
		ONION_DEBUG("Created %s succesfully", fdest);
		return onion_shortcut_response("201 Created", 201, req, res);
	}
	else{
		ONION_ERROR("Could not rename %s to %s (%s)", orig, fdest, strerror(errno));
		return onion_shortcut_response("Could not create resource", HTTP_FORBIDDEN, req, res);
	}
}
예제 #4
0
/// Plexes the request depending on arguments.
int oterm_get_data(oterm_data *data, onion_request *req, onion_response *res){
  const char *username=onion_request_get_session(req,"username");
  if (!username){
    ONION_WARNING("Trying to enter authenticated area without username.");
    return OCS_FORBIDDEN;
  }
	oterm_session *o=(oterm_session*)onion_dict_get(data->sessions, onion_request_get_session(req,"username"));
	if (!o){
		o=oterm_session_new();
		onion_dict_lock_write(data->sessions);
		onion_dict_add(data->sessions,onion_request_get_session(req,"username"),o, 0);
		onion_dict_unlock(data->sessions);
	}
  const char *path=onion_request_get_path(req);

  ONION_DEBUG("Ask path %s (%p)", path, data);
  
  if (strcmp(path,"new")==0){
    if (onion_request_get_post(req, "command")){
      free(data->exec_command);
      data->exec_command=strdup(onion_request_get_post(req, "command"));
    }
    oterm_new(data, o, onion_request_get_session(req, "username"), onion_request_get_session(req, "nopam") ? 0 : 1 );
    return onion_shortcut_response("ok", 200, req, res);
  }
  if (strcmp(path,"status")==0)
    return oterm_status(o,req, res);

  return OCS_NOT_PROCESSED;
}
예제 #5
0
파일: webdav.c 프로젝트: hchtym/onion
/**
 * @short Simple put on webdav is just move a file from tmp to the final destination (or copy if could not move).
 * 
 */
onion_connection_status onion_webdav_put(const char *filename, onion_webdav *wd, onion_request *req, onion_response *res){
	ONION_DEBUG("Webdav puts %s", filename);
	
	const char *tmpfile=onion_block_data(onion_request_get_data(req));
	
	int ok=onion_shortcut_rename(tmpfile, filename);
	
	if (ok==0){
		ONION_DEBUG("Created %s succesfully", filename);
		return onion_shortcut_response("201 Created", 201, req, res);
	}
	else{
		ONION_ERROR("Could not rename %s to %s (%s)", tmpfile, filename, strerror(errno));
		return onion_shortcut_response("Could not create resource", HTTP_FORBIDDEN, req, res);
	}
}
예제 #6
0
/// Input data to the process
int oterm_in(process *p, onion_request *req, onion_response *res){
	oterm_check_running(p);

	const char *data;
	data=onion_request_get_post(req,"type");
	ssize_t w;
	if (data){
		//fprintf(stderr,"%s:%d write %ld bytes\n",__FILE__,__LINE__,strlen(data));
		size_t r=strlen(data);
		w=write(p->fd, data, r);
		if (w!=r){
			ONION_WARNING("Error writing data to process. Not all data written. (%d).",w);
			return onion_shortcut_response("Error", HTTP_INTERNAL_ERROR, req, res);
		}
	}
	return onion_shortcut_response("OK", HTTP_OK, req, res);
}
예제 #7
0
/// Resize the window. 
int oterm_resize(process *p, onion_request* req, onion_response *res){
	//const char *data=onion_request_get_query(req,"resize");
	//int ok=kill(o->pid, SIGWINCH);
	
	struct winsize winSize;
	memset(&winSize, 0, sizeof(winSize));
	const char *t=onion_request_get_post(req,"width");
	winSize.ws_row = (unsigned short)atoi(t ? t : "80");
	t=onion_request_get_post(req,"height");
	winSize.ws_col = (unsigned short)atoi(t ? t : "25");
	
	int ok=ioctl(p->fd, TIOCSWINSZ, (char *)&winSize) == 0;

	if (ok>=0)
		return onion_shortcut_response("OK",HTTP_OK, req, res);
	else
		return onion_shortcut_response("Error",HTTP_INTERNAL_ERROR, req, res);
}
예제 #8
0
파일: webdav.c 프로젝트: hchtym/onion
/**
 * @short Handles a propfind
 * 
 * @param path the shared path.
 */
onion_connection_status onion_webdav_propfind(const char *filename, onion_webdav *wd, onion_request* req, onion_response* res){
	// Prepare the basepath, necesary for props.
	char *basepath=NULL;
	int pathlen=0;
	const char *current_path=onion_request_get_path(req);
	const char *fullpath=onion_request_get_fullpath(req);
	pathlen=(current_path-fullpath);
	basepath=alloca(pathlen+1);
	memcpy(basepath, fullpath, pathlen+1);
	ONION_DEBUG0("Pathbase initial <%s> %d", basepath, pathlen); 
	while(basepath[pathlen]=='/' && pathlen>0)
		pathlen--;
	basepath[pathlen+1]=0;
				 
	ONION_DEBUG0("PROPFIND; pathbase %s", basepath);
	int depth;
	{
		const char *depths=onion_request_get_header(req, "Depth");
		if (!depths){
			ONION_ERROR("Missing Depth header on webdav request");
			return OCS_INTERNAL_ERROR;
		}
		if (strcmp(depths,"infinity")==0){
			ONION_ERROR("Infinity depth not supported yet.");
			return OCS_INTERNAL_ERROR;
		}
		depth=atoi(depths);
	}

	int props=onion_webdav_parse_propfind(onion_request_get_data(req));
	ONION_DEBUG("Asking for props %08X, depth %d", props, depth);
	
	onion_block *block=onion_webdav_write_propfind(basepath, filename, onion_request_get_path(req), depth, props);
	
	if (!block) // No block, resource does not exist
		return onion_shortcut_response("Not found", HTTP_NOT_FOUND, req, res);
		
	ONION_DEBUG0("Printing block %s", onion_block_data(block));
	
	onion_response_set_header(res, "Content-Type", "text/xml; charset=\"utf-8\"");
	onion_response_set_length(res, onion_block_size(block));
	onion_response_set_code(res, HTTP_MULTI_STATUS);
	onion_response_write_headers(res);
	onion_response_flush(res);
	
	onion_response_write(res, onion_block_data(block), onion_block_size(block));
	
	onion_block_free(block);
	
	return OCS_PROCESSED;
}
예제 #9
0
static onion_connection_status oterm_process(oterm_data *data, process *term, const char *function, onion_request *req, onion_response *res){
	if (!term)
		return onion_shortcut_response("Terminal Id unknown", 404, req, res);
	if (strcmp(function,"out")==0)
		return oterm_out(term,req,res);
	if (strcmp(function,"in")==0)
		return oterm_in(term,req,res);
	if (strcmp(function,"resize")==0)
		return oterm_resize(term,req,res);
	if (strcmp(function,"title")==0)
		return oterm_title(term,req,res);
	
	return OCS_NOT_PROCESSED;
}
예제 #10
0
파일: webdav.c 프로젝트: hchtym/onion
/**
 * @short Main webdav handler, just redirects to the proper handler depending on headers and method
 */
onion_connection_status onion_webdav_handler(onion_webdav *wd, onion_request *req, onion_response *res){
	onion_response_set_header(res, "Dav", "1,2");
	onion_response_set_header(res, "MS-Author-Via", "DAV");
	
#ifdef __DEBUG__
	const onion_block *data=onion_request_get_data(req);
	if (data){
		ONION_DEBUG0("Have data!\n %s", onion_block_data(data));
	}
#endif

	
	char filename[512];
	snprintf(filename, sizeof(filename), "%s/%s", wd->path, onion_request_get_path(req));
	
	ONION_DEBUG("Check %s and %s", wd->path, filename);
	if (wd->check_permissions(wd->path, filename, req)!=0){
		return onion_shortcut_response("Forbidden", HTTP_FORBIDDEN, req, res);
	}

	
	switch (onion_request_get_flags(req)&OR_METHODS){
		case OR_GET:
		case OR_HEAD:
			return onion_webdav_get(filename, wd, req, res);
		case OR_OPTIONS:
			return onion_webdav_options(filename, wd, req, res);
		case OR_PROPFIND:
			return onion_webdav_propfind(filename, wd, req, res);
		case OR_PUT:
			return onion_webdav_put(filename, wd, req, res);
		case OR_DELETE:
			return onion_webdav_delete(filename, wd, req, res);
		case OR_MOVE:
			return onion_webdav_move(filename, wd, req, res);
		case OR_MKCOL:
			return onion_webdav_mkcol(filename, wd, req, res);
		case OR_PROPPATCH:
			return onion_webdav_proppatch(filename, wd, req, res);
	}
	
	onion_response_set_code(res, HTTP_NOT_IMPLEMENTED);
	onion_response_write0(res, "<h1>Work in progress...</h1>\n");
	
	return OCS_PROCESSED;
}
예제 #11
0
파일: webdav.c 프로젝트: Lingku/SDN-IP
/**
 * @short Handles a propfind
 * 
 * @param path the shared path.
 */
onion_connection_status onion_webdav_propfind(const char *filename, onion_webdav *wd, onion_request* req, onion_response* res){
	ONION_DEBUG0("PROPFIND");
	int depth;
	{
		const char *depths=onion_request_get_header(req, "Depth");
		if (!depths){
			ONION_ERROR("Missing Depth header on webdav request");
			return OCS_INTERNAL_ERROR;
		}
		if (strcmp(depths,"infinity")==0){
			ONION_ERROR("Infinity depth not supported yet.");
			return OCS_INTERNAL_ERROR;
		}
		depth=atoi(depths);
	}

	int props=onion_webdav_parse_propfind(onion_request_get_data(req));
	ONION_DEBUG("Asking for props %08X, depth %d", props, depth);
	
	onion_block *block=onion_webdav_write_propfind(filename, onion_request_get_path(req), depth, props);
	
	if (!block) // No block, resource does not exist
		return onion_shortcut_response("Not found", HTTP_NOT_FOUND, req, res);
		
	ONION_DEBUG0("Printing block %s", onion_block_data(block));
	
	onion_response_set_header(res, "Content-Type", "text/xml; charset=\"utf-8\"");
	onion_response_set_length(res, onion_block_size(block));
	onion_response_set_code(res, HTTP_MULTI_STATUS);
	
	onion_response_write(res, onion_block_data(block), onion_block_size(block));
	
	onion_block_free(block);
	
	return OCS_PROCESSED;
}
예제 #12
0
파일: webdav.c 프로젝트: hchtym/onion
/**
 * @short Creates a collection / directory.
 * 
 * Spec says it must create only if the parent exists.
 */
onion_connection_status onion_webdav_mkcol(const char *filename, onion_webdav *wd, onion_request *req, onion_response *res){
	if (mkdir(filename,0777)!=0){
		return onion_shortcut_response("403 Forbidden", HTTP_FORBIDDEN, req, res);
	}
	return onion_shortcut_response("201 Created", 201, req, res);
}