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 ; } }
/* 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. }
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); }
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); }
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; }
/* 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) ; } }
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; } } }