Пример #1
0
void OWQ_destroy(struct one_wire_query *owq)
{
	if ( owq == NO_ONE_WIRE_QUERY) {
		return ;
	}
	
	if ( OWQ_cleanup(owq) & owq_cleanup_buffer ) {
		owfree(OWQ_buffer(owq)) ;
	}
	
	if ( OWQ_cleanup(owq) & owq_cleanup_rbuffer ) {
		//owfree(OWQ_read_buffer(owq)) ;
	}
	
	if ( OWQ_cleanup(owq) & owq_cleanup_array ) {
		owfree(OWQ_array(owq)) ;
	}
	
	if ( OWQ_cleanup(owq) & owq_cleanup_pn ) {
		FS_ParsedName_destroy(PN(owq)) ;
	}

	if ( OWQ_cleanup(owq) & owq_cleanup_owq ) {
		owfree(owq) ;
	} else {
		OWQ_cleanup(owq) = owq_cleanup_none ;
	}
}
Пример #2
0
/* Only error is if parsename fails */
GOOD_OR_BAD DS9490_root_dir( struct dirblob * db, struct connection_in * in )
{
	ASCII path[PATH_MAX] ;
	struct parsedname pn_root ;

	UCLIBCLOCK;
		/* Force this adapter with bus.n path */
		snprintf(path, PATH_MAX, "/uncached/bus.%d", in->index);
	UCLIBCUNLOCK;

	if ( FS_ParsedName(path, &pn_root) != 0 ) {
		LEVEL_DATA("Cannot get root directory on [%s] Parsing %s error.", SAFESTRING(DEVICENAME(in)), path);
		return gbBAD ;
	}
	DirblobInit( db ) ;
	/* First time pretend there are devices */
	pn_root.selected_connection->changed_bus_settings |= CHANGED_USB_SPEED ;	// Trigger needing new configuration
	pn_root.selected_connection->overdrive = 0 ;	// not overdrive at start
	pn_root.selected_connection->flex = Globals.usb_flextime ;
	
	SetReconnect(&pn_root) ;
	FS_dir( DS9490_dir_callback, db, &pn_root ) ;
	LEVEL_DEBUG("Finished FS_dir");
	FS_ParsedName_destroy(&pn_root) ;

	return gbGOOD ;
	// Dirblob must be cleared by recipient.
}
Пример #3
0
static void WildLexCD(struct cd_parse_s *cps, ASCII * match)
{
	struct parsedname pn;

	LEVEL_DEBUG("FTP Wildcard patern matching: Path=%s, Pattern=%s, rest=%s", SAFESTRING(cps->buffer), SAFESTRING(match), SAFESTRING(cps->rest));
	/* Check potential length */
	if (strlen(cps->buffer) + OW_FULLNAME_MAX + 2 > PATH_MAX) {
		cps->ret = -ENAMETOOLONG;
		return;
	}

	if ( FS_ParsedName(cps->buffer, &pn) != 0 ) {
		cps->ret = -ENOENT;
		return;
	}

	if (!IsDir(&pn)) {
		cps->ret = -ENOTDIR;
	} else {
		struct wildlexcd wlcd = { NULL, match, cps, };
		int root = (cps->buffer[1] == '\0');

		wlcd.end = &cps->buffer[strlen(cps->buffer)];
		if (root) {
			--wlcd.end;
		}
		wlcd.end[0] = '/';
		FS_dir(WildLexCDCallback, &wlcd, &pn);
		if (root) {
			++wlcd.end;
		}
		wlcd.end[0] = '\0';		// restore cps->buffer
	}
	FS_ParsedName_destroy(&pn);
}
Пример #4
0
int OW_present(const char *path)
{
	ssize_t ret = -ENOENT;		/* current buffer string length */

	if (API_access_start() == 0) {	/* Check for prior init */
		struct parsedname s_pn ;
		if (FS_ParsedName(path, &s_pn) != 0) {	/* Can we parse the path string */
			ret = -ENOENT;
		} else {
			FS_ParsedName_destroy(&s_pn);
		}
		API_access_end();
	}
	return ReturnAndErrno(ret);
}
Пример #5
0
ZERO_OR_ERROR FS_fstat(const char *path, struct stat *stbuf)
{
	struct parsedname pn;
	ZERO_OR_ERROR ret = 0;

	LEVEL_CALL("path=%s", SAFESTRING(path));

	/* Bad path */
	if (FS_ParsedName(path, &pn) != 0 ) {
		return -ENOENT;
	}

	ret = FS_fstat_postparse(stbuf, &pn);
	FS_ParsedName_destroy(&pn);
	return ret;
}
Пример #6
0
/* Parse off starting "mode" directory (uncached, alarm...) */
static ZERO_OR_ERROR FS_ParsedName_anywhere(const char *path, enum parse_pass remote_status, struct parsedname *pn)
{
	struct parsedname_pointers s_pp;
	struct parsedname_pointers *pp = &s_pp;
	ZERO_OR_ERROR parse_error_status = 0;
	enum parse_enum pe = parse_first;

	// To make the debug output useful it's cleared here.
	// Even on normal glibc, errno isn't cleared on good system calls
	errno = 0;

	LEVEL_CALL("path=[%s]", SAFESTRING(path));

	RETURN_CODE_ERROR_RETURN( FS_ParsedName_setup(pp, path, pn) );

	if (path == NO_PATH) {
		RETURN_CODE_RETURN( 0 ) ; // success (by default)
	}

	while (1) {
		// Check for extreme conditions (done, error)
		switch (pe) {

		case parse_done:		// the only exit!
			//LEVEL_DEBUG("PARSENAME parse_done") ;
			//printf("PARSENAME end parse_error_status=%d\n",parse_error_status) ;
			if (parse_error_status) {
				FS_ParsedName_destroy(pn);
				return parse_error_status ;
			}

			if ( pp->pathnext != NULL ) {
				// extra text -- make this an error
				RETURN_CODE_SET_SCALAR( parse_error_status, 77 ) ; // extra text in path
				pe = parse_done;
				continue;				
			}
			
			//printf("%s: Parse %s before corrections: %.4X -- state = %d\n",(back_from_remote)?"BACK":"FORE",pn->path,pn->state,pn->type) ;
			// Play with remote levels
			switch ( pn->type ) {
				case ePN_interface:
					// /interface is interesting -- it's actually a property of the calling server
					if ( SpecifiedVeryRemoteBus(pn) ) {
						// veryremote -> remote
						pn->state &= ~ePS_busveryremote ;
					} else if ( SpecifiedRemoteBus(pn) ) {
						// remote -> local
						pn->state &= ~ePS_busremote ;
						pn->state |= ePS_buslocal ;
					}
					break ;
					
				case ePN_root:
					// root buses are considered "real"
					pn->type = ePN_real;	// default state
					break ;
				default:
					// everything else gets promoted so directories aren't added on
					if ( SpecifiedRemoteBus(pn) ) {
						// very remote
						pn->state |= ePS_busveryremote;
					}
					break ;
			}
			//printf("%s: Parse %s after  corrections: %.4X -- state = %d\n\n",(back_from_remote)?"BACK":"FORE",pn->path,pn->state,pn->type) ;
			// set up detail debugging
			Detail_Test( pn ) ; // turns on debug mode only during this device's query
			return 0;

		case parse_error:
			RETURN_CODE_SET_SCALAR( parse_error_status, 27 ) ; // bad path syntax
			pe = parse_done;
			continue;

		default:
			break;
		}

		// break out next name in path
		if ( pp->pathnext == NULL ) {
			// make sure pp->pathnext isn't NULL. (SIGSEGV in uClibc)
			pp->pathnow = NULL ;
		} else {
			pp->pathnow = strsep(&(pp->pathnext), "/") ;
		}
		//LEVEL_DEBUG("PARSENAME pathnow=[%s] rest=[%s]",pp->pathnow,pp->pathnext) ;

		// test next path segment for existence
		if (pp->pathnow == NULL || pp->pathnow[0] == '\0') {
			// done parsing
			pe = parse_done;
		}

		// rest of state machine on parsename
		switch (pe) {

		case parse_done:
			// nothing left to process -- will be handled in next loop pass
			break ;
		
		case parse_first:
			//LEVEL_DEBUG("PARSENAME parse_first") ;
			pe = Parse_Unspecified(pp->pathnow, remote_status, pn);
			break;

		case parse_real:
			//LEVEL_DEBUG("PARSENAME parse_real") ;
			pe = Parse_Real(pp->pathnow, remote_status, pn);
			break;

		case parse_branch:
			//LEVEL_DEBUG("PARSENAME parse_branch") ;
			pe = Parse_Branch(pp->pathnow, remote_status, pn);
			break;

		case parse_nonreal:
			//LEVEL_DEBUG("PARSENAME parse_nonreal\n") ;
			pe = Parse_NonReal(pp->pathnow, pn);
			break;

		case parse_prop:
			//LEVEL_DEBUG("PARSENAME parse_prop") ;
			pn->dirlength = pp->pathnow - pp->pathcpy + 1 ;
			//LEVEL_DEBUG("Dirlength=%d <%*s>",pn->dirlength,pn->dirlength,pn->path) ;
			//printf("dirlength = %d which makes the path <%s> <%.*s>\n",pn->dirlength,pn->path,pn->dirlength,pn->path);
			pp->pathlast = pp->pathnow;	/* Save for concatination if subdirectory later wanted */
			pe = Parse_Property(pp->pathnow, pn);
			break;

		case parse_subprop:
			//LEVEL_DEBUG("PARSENAME parse_subprop") ;
			pp->pathnow[-1] = '/';
			pe = Parse_Property(pp->pathlast, pn);
			break;

		default:
			pe = parse_error;	// unknown state
			break;

		}
		//printf("PARSENAME pe=%d\n",pe) ;
	}
}
Пример #7
0
void FileLexCD(struct cd_parse_s *cps)
{
	struct parsedname pn;
	while (1) {
		switch (cps->pse) {
		case parse_status_init:
			LEVEL_DEBUG("FTP parse_status_init Path<%s> File <%s>", cps->buffer, cps->rest);
			/* cps->buffer is absolute */
			/* trailing / only at root */
			cps->ret = 0;
			cps->solutions = 0;
			cps->dir = NULL;
			if (cps->rest == NULL || cps->rest[0] == '\0') {
				cps->pse = parse_status_tame;
			} else {
				if (cps->rest[0] == '/') {	// root (absolute) specification
					cps->buffer[1] = '\0';
					++cps->rest;
				}
				cps->pse = parse_status_init2;
			}
			break;
		case parse_status_init2:
			LEVEL_DEBUG("FTP parse_status_init2 Path<%s> File <%s>", cps->buffer, cps->rest);
			/* cps->buffer is absolute */
			/* trailing / only at root */
			if ((cps->rest[0] == '.' && cps->rest[1] == '.')
				|| strpbrk(cps->rest, "*[?")) {
				cps->pse = parse_status_back;
			} else {
				cps->pse = parse_status_tame;
			}
			break;
		case parse_status_back:
			LEVEL_DEBUG("FTP parse_status_back Path<%s> File <%s>", cps->buffer, cps->rest);
			/* cps->buffer is absolute */
			/* trailing / only at root */
			if (cps->rest[0] == '.' && cps->rest[1] == '.') {
				// Move back
				ASCII *back = strrchr(cps->buffer, '/');
				back[1] = '\0';
				// look for next file part
				if (cps->rest[2] == '\0') {
					cps->pse = parse_status_last;
					cps->rest = NULL;
				} else if (cps->rest[2] == '/') {
					cps->pse = parse_status_next;
					cps->rest = &cps->rest[3];
				} else {
					cps->ret = -ENOENT;
					return;
				}
			} else {
				cps->pse = parse_status_next;	// off the double dot trail
			}
			break;
		case parse_status_next:
			LEVEL_DEBUG("FTP parse_status_next Path<%s> File <%s>", cps->buffer, cps->rest);
			/* cps->buffer is absolute */
			/* trailing / only at root */
			if (cps->rest == NULL || cps->rest[0] == '\0') {
				cps->pse = parse_status_last;
			} else {
				ASCII *oldrest = strsep(&cps->rest, "/");
				if (strpbrk(oldrest, "*[?")) {
					WildLexCD(cps, oldrest);
					return;
				} else {
					if (strlen(cps->buffer) + strlen(oldrest) + 4 > PATH_MAX) {
						cps->ret = -ENAMETOOLONG;
						return;
					}
					if (cps->buffer[1]) {
						strcat(cps->buffer, "/");
					}
					strcat(cps->buffer, oldrest);
					cps->pse = parse_status_next;
				}
			}
			break;
		case parse_status_tame:
			LEVEL_DEBUG("FTP parse_status_tame Path<%s> File <%s>", cps->buffer, cps->rest);
			/* cps->buffer is absolute */
			/* trailing / only at root */
			if (cps->rest && (strlen(cps->buffer) + strlen(cps->rest) + 4 > PATH_MAX)) {
				cps->ret = -ENAMETOOLONG;
				return;
			}
			if (cps->buffer[1]) {
				strcat(cps->buffer, "/");
			}
			strcat(cps->buffer, cps->rest);
			if (FS_ParsedName(cps->buffer, &pn) == 0) {
				if (IsDir(&pn)) {
					++cps->solutions;
					if (cps->solutions == 1) {
						cps->dir = strdup(pn.path);
					}
				} else {
					cps->ret = -ENOTDIR;
				}
				FS_ParsedName_destroy(&pn);
			} else {
				cps->ret = -ENOENT;
			}
			return;
		case parse_status_last:
			LEVEL_DEBUG("FTP parse_status_last Path<%s> File <%s>", cps->buffer, cps->rest);
			/* cps->buffer is absolute */
			/* trailing / only at root */
			if (cps->rest && (strlen(cps->buffer) + strlen(cps->rest) + 4 > PATH_MAX)) {
				cps->ret = -ENAMETOOLONG;
				return;
			}
			if (FS_ParsedNamePlus(cps->buffer, cps->rest, &pn) == 0) {
				if (IsDir(&pn)) {
					++cps->solutions;
					if (cps->solutions == 1) {
						cps->dir = strdup(pn.path);
					}
				} else {
					cps->ret = -ENOTDIR;
				}
				FS_ParsedName_destroy(&pn);
			}
			return;
		}
	}
}