// go searching through a single dir for a name match. use MyStrcmp() // for case-insensitive compare. use '/' to separate directory components // if more after '/' and we matched a dir, recurse down there // RETURN: ptr to dir entry if found, else 0 // once any dir matched, don't return name which dir was matched dir_t *FindNameSub( char *name, dir_t *this_dir ) { dir_t *dir_p = this_dir; int len = MyStrlen( name ); char *p; // if name ends in '/', chances are we need to decend into the dir if( ( p = strchr( name, '/' ) ) != NULL) len = p - name; for( ; dir_p->name; dir_p++ ) { if( 1 == MyStrcmp( name, dir_p->name, len ) ) { if( p && p[1] != 0 ) { // user is trying for a sub-dir. if there are more components, make sure this // is a dir. if name ends with "/" we don't check. thus "hello.html/" is legal while( *p == '/' ) { p++; if( '\0' == *p ) return dir_p; // "/README/////" is OK } name = p; return FindNameSub( name, (dir_t *)dir_p->data ); } return dir_p; } } return NULL; // no match found }
int main() { char a[80]; unsigned int len; printf("please enter a string:\n"); gets(a); len=MyStrlen( a); printf("The lenth you input is:%u",len); }
// get info about a specific obj. if not found, returns an error code. int ChkObj( char *name, attr_t *attr_p ) { dir_t *dir_p = FindName( name ); if( ! dir_p ) return UNFOUND; Dir2Attr( dir_p, attr_p ); // copy what dir_p points to to where attr_p points to // this should be included to pass the filename (add 1 to length for null) MyMemcpy( (char *)( attr_p + 1 ), dir_p->name, MyStrlen( dir_p->name ) + 1 ); return GOOD; }
// Copy bytes from file into user's buffer. Returns actual count of bytes // transferred. Read from fd_array[fd].offset (initially given 0) for // buff_size in bytes, and record the offset. may reach FM_EOF though... int ReadObj( int fd, char *buff, int owner, int *lp_actual ) { int result; int remaining; dir_t *lp_dir; *lp_actual=0; result = CanAccessFD( fd, owner ); // check if owner owns the fd if( result != GOOD ) return result; lp_dir = fd_array[fd].item; if( A_ISDIR(lp_dir->mode ) ) { // it's a dir // if reading directory, return attr_t structure followed by an obj name. // a chunk returned per read. `offset' is index into root_dir[] table. dir_t *this_dir = lp_dir; attr_t *attr_p = (attr_t *)buff; dir_t *dir_p; if( 101 < sizeof( *attr_p ) + 2) return BUF_SMALL; // use current dir, advance to next dir for next time when called do { dir_p = ( (dir_t *)this_dir->data ); dir_p += fd_array[fd].offset ; if( dir_p->inode == END_DIR_INODE ) return FM_EOF; fd_array[fd].offset++; // advance } while( dir_p->name == NULL ); // MyBzero() fills buff with 0's, necessary to clean buff // since Dir2Attr may not completely overwrite whole buff... MyBzero( buff, 101 ); Dir2Attr( dir_p, attr_p ); // copy obj name after attr_t, add 1 to length for null MyMemcpy((char *)( attr_p + 1 ), dir_p->name, MyStrlen( dir_p->name ) + 1); // *lp_actual = sizeof(*dir_p) + MyStrlen((char *)(attr_p + 1)) + 1; *lp_actual = sizeof( attr_t ) + MyStrlen( dir_p->name ) + 1; } else { // a file, not dir // compute max # of bytes can transfer then MyMemcpy() remaining = lp_dir->size - fd_array[fd].offset; if( remaining == 0 ) return FM_EOF; MyBzero( buff, 101 ); // null termination for any part of file read result = remaining<100?remaining:100; // -1 saving is for last NULL MyMemcpy( buff, &lp_dir->data[ fd_array[ fd ].offset ], result ); fd_array[fd].offset += result; // advance our "current" ptr *lp_actual = result; } return GOOD; }