データ構造 | |
struct | name_cache_entry |
struct | smb_Dir |
struct | dptr_struct |
関数 | |
void | make_dir_struct (char *buf, const char *mask, const char *fname, SMB_OFF_T size, uint32 mode, time_t date, BOOL uc) |
void | init_dptrs (void) |
static void | dptr_idle (struct dptr_struct *dptr) |
static void | dptr_idleoldest (void) |
static struct dptr_struct * | dptr_get (int key, BOOL forclose) |
char * | dptr_path (int key) |
char * | dptr_wcard (int key) |
uint16 | dptr_attr (int key) |
static void | dptr_close_internal (struct dptr_struct *dptr) |
void | dptr_close (int *key) |
void | dptr_closecnum (connection_struct *conn) |
void | dptr_idlecnum (connection_struct *conn) |
void | dptr_closepath (char *path, uint16 spid) |
static void | dptr_close_oldest (BOOL old) |
NTSTATUS | dptr_create (connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close, uint16 spid, const char *wcard, BOOL wcard_has_wild, uint32 attr, struct dptr_struct **dptr_ret) |
int | dptr_CloseDir (struct dptr_struct *dptr) |
void | dptr_SeekDir (struct dptr_struct *dptr, long offset) |
long | dptr_TellDir (struct dptr_struct *dptr) |
BOOL | dptr_has_wild (struct dptr_struct *dptr) |
int | dptr_dnum (struct dptr_struct *dptr) |
static const char * | dptr_normal_ReadDirName (struct dptr_struct *dptr, long *poffset, SMB_STRUCT_STAT *pst) |
const char * | dptr_ReadDirName (struct dptr_struct *dptr, long *poffset, SMB_STRUCT_STAT *pst) |
BOOL | dptr_SearchDir (struct dptr_struct *dptr, const char *name, long *poffset, SMB_STRUCT_STAT *pst) |
void | dptr_DirCacheAdd (struct dptr_struct *dptr, const char *name, long offset) |
BOOL | dptr_fill (char *buf1, unsigned int key) |
dptr_struct * | dptr_fetch (char *buf, int *num) |
dptr_struct * | dptr_fetch_lanman2 (int dptr_num) |
BOOL | dir_check_ftype (connection_struct *conn, uint32 mode, uint32 dirtype) |
static BOOL | mangle_mask_match (connection_struct *conn, fstring filename, char *mask) |
BOOL | get_dir_entry (connection_struct *conn, char *mask, uint32 dirtype, pstring fname, SMB_OFF_T *size, uint32 *mode, time_t *date, BOOL check_descend) |
static BOOL | user_can_read_file (connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) |
static BOOL | user_can_write_file (connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) |
static BOOL | file_is_special (connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) |
BOOL | is_visible_file (connection_struct *conn, const char *dir_path, const char *name, SMB_STRUCT_STAT *pst, BOOL use_veto) |
smb_Dir * | OpenDir (connection_struct *conn, const char *name, const char *mask, uint32 attr) |
int | CloseDir (struct smb_Dir *dirp) |
const char * | ReadDirName (struct smb_Dir *dirp, long *poffset) |
void | RewindDir (struct smb_Dir *dirp, long *poffset) |
void | SeekDir (struct smb_Dir *dirp, long offset) |
long | TellDir (struct smb_Dir *dirp) |
void | DirCacheAdd (struct smb_Dir *dirp, const char *name, long offset) |
BOOL | SearchDir (struct smb_Dir *dirp, const char *name, long *poffset) |
NTSTATUS | can_delete_directory (struct connection_struct *conn, const char *dirname) |
変数 | |
current_user | current_user |
static struct bitmap * | dptr_bmap |
static struct dptr_struct * | dirptrs |
static int | dirhandles_open = 0 |
void make_dir_struct | ( | char * | buf, | |
const char * | mask, | |||
const char * | fname, | |||
SMB_OFF_T | size, | |||
uint32 | mode, | |||
time_t | date, | |||
BOOL | uc | |||
) |
参照先 push_ascii()・srv_put_dos_date()・strchr_m().
参照元 reply_search().
00077 { 00078 char *p; 00079 pstring mask2; 00080 00081 pstrcpy(mask2,mask); 00082 00083 if ((mode & aDIR) != 0) 00084 size = 0; 00085 00086 memset(buf+1,' ',11); 00087 if ((p = strchr_m(mask2,'.')) != NULL) { 00088 *p = 0; 00089 push_ascii(buf+1,mask2,8, 0); 00090 push_ascii(buf+9,p+1,3, 0); 00091 *p = '.'; 00092 } else 00093 push_ascii(buf+1,mask2,11, 0); 00094 00095 memset(buf+21,'\0',DIR_STRUCT_SIZE-21); 00096 SCVAL(buf,21,mode); 00097 srv_put_dos_date(buf,22,date); 00098 SSVAL(buf,26,size & 0xFFFF); 00099 SSVAL(buf,28,(size >> 16)&0xFFFF); 00100 /* We only uppercase if FLAGS2_LONG_PATH_COMPONENTS is zero in the input buf. 00101 Strange, but verified on W2K3. Needed for OS/2. JRA. */ 00102 push_ascii(buf+30,fname,12, uc ? STR_UPPER : 0); 00103 DEBUG(8,("put name [%s] from [%s] into dir struct\n",buf+30, fname)); 00104 }
void init_dptrs | ( | void | ) |
参照先 bitmap_allocate()・dptr_bmap・exit_server().
参照元 init_structs().
00111 { 00112 static BOOL dptrs_init=False; 00113 00114 if (dptrs_init) 00115 return; 00116 00117 dptr_bmap = bitmap_allocate(MAX_DIRECTORY_HANDLES); 00118 00119 if (!dptr_bmap) 00120 exit_server("out of memory in init_dptrs"); 00121 00122 dptrs_init = True; 00123 }
static void dptr_idle | ( | struct dptr_struct * | dptr | ) | [static] |
参照先 CloseDir()・dptr_struct::dir_hnd・dptr_struct::dnum.
参照元 dptr_idlecnum()・dptr_idleoldest().
00130 { 00131 if (dptr->dir_hnd) { 00132 DEBUG(4,("Idling dptr dnum %d\n",dptr->dnum)); 00133 CloseDir(dptr->dir_hnd); 00134 dptr->dir_hnd = NULL; 00135 } 00136 }
static void dptr_idleoldest | ( | void | ) | [static] |
参照先 dptr_struct::dir_hnd・dirptrs・dptr_idle()・dptr_struct::next・dptr_struct::prev.
参照元 dptr_create()・dptr_get().
00143 { 00144 struct dptr_struct *dptr; 00145 00146 /* 00147 * Go to the end of the list. 00148 */ 00149 for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next) 00150 ; 00151 00152 if(!dptr) { 00153 DEBUG(0,("No dptrs available to idle ?\n")); 00154 return; 00155 } 00156 00157 /* 00158 * Idle the oldest pointer. 00159 */ 00160 00161 for(; dptr; dptr = dptr->prev) { 00162 if (dptr->dir_hnd) { 00163 dptr_idle(dptr); 00164 return; 00165 } 00166 } 00167 }
static struct dptr_struct* dptr_get | ( | int | key, | |
BOOL | forclose | |||
) | [static] |
参照先 dptr_struct::attr・dptr_struct::conn・dptr_struct::dir_hnd・dirhandles_open・dirptrs・dptr_struct::dnum・dptr_idleoldest()・errno・dptr_struct::next・OpenDir()・dptr_struct::path・strerror()・dptr_struct::wcard.
参照元 dptr_attr()・dptr_close()・dptr_fetch()・dptr_fetch_lanman2()・dptr_fill()・dptr_path()・dptr_wcard().
00174 { 00175 struct dptr_struct *dptr; 00176 00177 for(dptr = dirptrs; dptr; dptr = dptr->next) { 00178 if(dptr->dnum == key) { 00179 if (!forclose && !dptr->dir_hnd) { 00180 if (dirhandles_open >= MAX_OPEN_DIRECTORIES) 00181 dptr_idleoldest(); 00182 DEBUG(4,("dptr_get: Reopening dptr key %d\n",key)); 00183 if (!(dptr->dir_hnd = OpenDir(dptr->conn, dptr->path, dptr->wcard, dptr->attr))) { 00184 DEBUG(4,("dptr_get: Failed to open %s (%s)\n",dptr->path, 00185 strerror(errno))); 00186 return False; 00187 } 00188 } 00189 DLIST_PROMOTE(dirptrs,dptr); 00190 return dptr; 00191 } 00192 } 00193 return(NULL); 00194 }
char* dptr_path | ( | int | key | ) |
参照先 dptr_get()・dptr_struct::path.
参照元 call_trans2findfirst()・call_trans2findnext()・dptr_fetch()・dptr_fetch_lanman2()・reply_search().
00201 { 00202 struct dptr_struct *dptr = dptr_get(key, False); 00203 if (dptr) 00204 return(dptr->path); 00205 return(NULL); 00206 }
char* dptr_wcard | ( | int | key | ) |
参照先 dptr_get()・dptr_struct::wcard.
参照元 call_trans2findnext()・reply_search().
00213 { 00214 struct dptr_struct *dptr = dptr_get(key, False); 00215 if (dptr) 00216 return(dptr->wcard); 00217 return(NULL); 00218 }
uint16 dptr_attr | ( | int | key | ) |
参照先 dptr_struct::attr・dptr_get().
参照元 call_trans2findnext()・reply_search().
00225 { 00226 struct dptr_struct *dptr = dptr_get(key, False); 00227 if (dptr) 00228 return(dptr->attr); 00229 return(0); 00230 }
static void dptr_close_internal | ( | struct dptr_struct * | dptr | ) | [static] |
参照先 bitmap_clear()・bitmap_query()・CloseDir()・dptr_struct::dir_hnd・dirptrs・dptr_struct::dnum・dptr_bmap・dptr_struct::path・string_set()・dptr_struct::wcard.
参照元 dptr_close()・dptr_close_oldest()・dptr_closecnum()・dptr_closepath().
00237 { 00238 DEBUG(4,("closing dptr key %d\n",dptr->dnum)); 00239 00240 DLIST_REMOVE(dirptrs, dptr); 00241 00242 /* 00243 * Free the dnum in the bitmap. Remember the dnum value is always 00244 * biased by one with respect to the bitmap. 00245 */ 00246 00247 if(bitmap_query( dptr_bmap, dptr->dnum - 1) != True) { 00248 DEBUG(0,("dptr_close_internal : Error - closing dnum = %d and bitmap not set !\n", 00249 dptr->dnum )); 00250 } 00251 00252 bitmap_clear(dptr_bmap, dptr->dnum - 1); 00253 00254 if (dptr->dir_hnd) { 00255 CloseDir(dptr->dir_hnd); 00256 } 00257 00258 /* Lanman 2 specific code */ 00259 SAFE_FREE(dptr->wcard); 00260 string_set(&dptr->path,""); 00261 SAFE_FREE(dptr); 00262 }
void dptr_close | ( | int * | key | ) |
参照先 dirptrs・dptr_close_internal()・dptr_get()・dptr_struct::next.
参照元 call_trans2findfirst()・call_trans2findnext()・reply_fclose()・reply_findclose()・reply_search().
00269 { 00270 struct dptr_struct *dptr; 00271 00272 if(*key == INVALID_DPTR_KEY) 00273 return; 00274 00275 /* OS/2 seems to use -1 to indicate "close all directories" */ 00276 if (*key == -1) { 00277 struct dptr_struct *next; 00278 for(dptr = dirptrs; dptr; dptr = next) { 00279 next = dptr->next; 00280 dptr_close_internal(dptr); 00281 } 00282 *key = INVALID_DPTR_KEY; 00283 return; 00284 } 00285 00286 dptr = dptr_get(*key, True); 00287 00288 if (!dptr) { 00289 DEBUG(0,("Invalid key %d given to dptr_close\n", *key)); 00290 return; 00291 } 00292 00293 dptr_close_internal(dptr); 00294 00295 *key = INVALID_DPTR_KEY; 00296 }
void dptr_closecnum | ( | connection_struct * | conn | ) |
参照先 dptr_struct::conn・dirptrs・dptr_close_internal()・dptr_struct::next.
参照元 close_cnum().
00303 { 00304 struct dptr_struct *dptr, *next; 00305 for(dptr = dirptrs; dptr; dptr = next) { 00306 next = dptr->next; 00307 if (dptr->conn == conn) 00308 dptr_close_internal(dptr); 00309 } 00310 }
void dptr_idlecnum | ( | connection_struct * | conn | ) |
参照先 dptr_struct::conn・dptr_struct::dir_hnd・dirptrs・dptr_idle()・dptr_struct::next.
参照元 conn_idle_all().
00317 { 00318 struct dptr_struct *dptr; 00319 for(dptr = dirptrs; dptr; dptr = dptr->next) { 00320 if (dptr->conn == conn && dptr->dir_hnd) 00321 dptr_idle(dptr); 00322 } 00323 }
void dptr_closepath | ( | char * | path, | |
uint16 | spid | |||
) |
参照先 dirptrs・dptr_close_internal()・dptr_struct::next・dptr_struct::path・dptr_struct::spid・strequal().
参照元 reply_rmdir().
00330 { 00331 struct dptr_struct *dptr, *next; 00332 for(dptr = dirptrs; dptr; dptr = next) { 00333 next = dptr->next; 00334 if (spid == dptr->spid && strequal(dptr->path,path)) 00335 dptr_close_internal(dptr); 00336 } 00337 }
static void dptr_close_oldest | ( | BOOL | old | ) | [static] |
参照先 dirptrs・dptr_struct::dnum・dptr_close_internal()・dptr_struct::expect_close・dptr_struct::next・dptr_struct::prev.
参照元 dptr_create().
00346 { 00347 struct dptr_struct *dptr; 00348 00349 /* 00350 * Go to the end of the list. 00351 */ 00352 for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next) 00353 ; 00354 00355 if(!dptr) { 00356 DEBUG(0,("No old dptrs available to close oldest ?\n")); 00357 return; 00358 } 00359 00360 /* 00361 * If 'old' is true, close the oldest oldhandle dnum (ie. 1 < dnum < 256) that 00362 * does not have expect_close set. If 'old' is false, close 00363 * one of the new dnum handles. 00364 */ 00365 00366 for(; dptr; dptr = dptr->prev) { 00367 if ((old && (dptr->dnum < 256) && !dptr->expect_close) || 00368 (!old && (dptr->dnum > 255))) { 00369 dptr_close_internal(dptr); 00370 return; 00371 } 00372 } 00373 }
NTSTATUS dptr_create | ( | connection_struct * | conn, | |
pstring | path, | |||
BOOL | old_handle, | |||
BOOL | expect_close, | |||
uint16 | spid, | |||
const char * | wcard, | |||
BOOL | wcard_has_wild, | |||
uint32 | attr, | |||
struct dptr_struct ** | dptr_ret | |||
) |
参照先 dptr_struct::attr・bitmap_clear()・bitmap_find()・bitmap_set()・check_name()・CloseDir()・dptr_struct::conn・smb_Dir::conn・dptr_struct::dir_hnd・dirhandles_open・connection_struct::dirpath・dirptrs・dptr_struct::dnum・dptr_bmap・dptr_close_oldest()・dptr_idleoldest()・errno・dptr_struct::expect_close・dptr_struct::has_wild・map_nt_error_from_unix()・OpenDir()・dptr_struct::path・dptr_struct::spid・status・string_set()・dptr_struct::wcard.
参照元 call_trans2findfirst()・reply_search().
00386 { 00387 struct dptr_struct *dptr = NULL; 00388 struct smb_Dir *dir_hnd; 00389 const char *dir2; 00390 NTSTATUS status; 00391 00392 DEBUG(5,("dptr_create dir=%s\n", path)); 00393 00394 if (!wcard) { 00395 return NT_STATUS_INVALID_PARAMETER; 00396 } 00397 00398 status = check_name(conn,path); 00399 if (!NT_STATUS_IS_OK(status)) { 00400 return status; 00401 } 00402 00403 /* use a const pointer from here on */ 00404 dir2 = path; 00405 if (!*dir2) 00406 dir2 = "."; 00407 00408 dir_hnd = OpenDir(conn, dir2, wcard, attr); 00409 if (!dir_hnd) { 00410 return map_nt_error_from_unix(errno); 00411 } 00412 00413 string_set(&conn->dirpath,dir2); 00414 00415 if (dirhandles_open >= MAX_OPEN_DIRECTORIES) { 00416 dptr_idleoldest(); 00417 } 00418 00419 dptr = SMB_MALLOC_P(struct dptr_struct); 00420 if(!dptr) { 00421 DEBUG(0,("malloc fail in dptr_create.\n")); 00422 CloseDir(dir_hnd); 00423 return NT_STATUS_NO_MEMORY; 00424 } 00425 00426 ZERO_STRUCTP(dptr); 00427 00428 if(old_handle) { 00429 00430 /* 00431 * This is an old-style SMBsearch request. Ensure the 00432 * value we return will fit in the range 1-255. 00433 */ 00434 00435 dptr->dnum = bitmap_find(dptr_bmap, 0); 00436 00437 if(dptr->dnum == -1 || dptr->dnum > 254) { 00438 00439 /* 00440 * Try and close the oldest handle not marked for 00441 * expect close in the hope that the client has 00442 * finished with that one. 00443 */ 00444 00445 dptr_close_oldest(True); 00446 00447 /* Now try again... */ 00448 dptr->dnum = bitmap_find(dptr_bmap, 0); 00449 if(dptr->dnum == -1 || dptr->dnum > 254) { 00450 DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum)); 00451 SAFE_FREE(dptr); 00452 CloseDir(dir_hnd); 00453 return NT_STATUS_TOO_MANY_OPENED_FILES; 00454 } 00455 } 00456 } else { 00457 00458 /* 00459 * This is a new-style trans2 request. Allocate from 00460 * a range that will return 256 - MAX_DIRECTORY_HANDLES. 00461 */ 00462 00463 dptr->dnum = bitmap_find(dptr_bmap, 255); 00464 00465 if(dptr->dnum == -1 || dptr->dnum < 255) { 00466 00467 /* 00468 * Try and close the oldest handle close in the hope that 00469 * the client has finished with that one. This will only 00470 * happen in the case of the Win98 client bug where it leaks 00471 * directory handles. 00472 */ 00473 00474 dptr_close_oldest(False); 00475 00476 /* Now try again... */ 00477 dptr->dnum = bitmap_find(dptr_bmap, 255); 00478 00479 if(dptr->dnum == -1 || dptr->dnum < 255) { 00480 DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum)); 00481 SAFE_FREE(dptr); 00482 CloseDir(dir_hnd); 00483 return NT_STATUS_TOO_MANY_OPENED_FILES; 00484 } 00485 } 00486 } 00487 00488 bitmap_set(dptr_bmap, dptr->dnum); 00489 00490 dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */ 00491 00492 string_set(&dptr->path,dir2); 00493 dptr->conn = conn; 00494 dptr->dir_hnd = dir_hnd; 00495 dptr->spid = spid; 00496 dptr->expect_close = expect_close; 00497 dptr->wcard = SMB_STRDUP(wcard); 00498 if (!dptr->wcard) { 00499 bitmap_clear(dptr_bmap, dptr->dnum - 1); 00500 SAFE_FREE(dptr); 00501 CloseDir(dir_hnd); 00502 return NT_STATUS_NO_MEMORY; 00503 } 00504 if (lp_posix_pathnames() || (wcard[0] == '.' && wcard[1] == 0)) { 00505 dptr->has_wild = True; 00506 } else { 00507 dptr->has_wild = wcard_has_wild; 00508 } 00509 00510 dptr->attr = attr; 00511 00512 DLIST_ADD(dirptrs, dptr); 00513 00514 DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n", 00515 dptr->dnum,path,expect_close)); 00516 00517 *dptr_ret = dptr; 00518 00519 return NT_STATUS_OK; 00520 }
int dptr_CloseDir | ( | struct dptr_struct * | dptr | ) |
void dptr_SeekDir | ( | struct dptr_struct * | dptr, | |
long | offset | |||
) |
long dptr_TellDir | ( | struct dptr_struct * | dptr | ) |
BOOL dptr_has_wild | ( | struct dptr_struct * | dptr | ) |
int dptr_dnum | ( | struct dptr_struct * | dptr | ) |
参照先 dptr_struct::dnum.
参照元 call_trans2findfirst()・reply_search().
00549 { 00550 return dptr->dnum; 00551 }
static const char* dptr_normal_ReadDirName | ( | struct dptr_struct * | dptr, | |
long * | poffset, | |||
SMB_STRUCT_STAT * | pst | |||
) | [static] |
参照先 dptr_struct::conn・dptr_struct::dir_hnd・is_visible_file()・name・dptr_struct::path・ReadDirName().
参照元 dptr_ReadDirName().
00558 { 00559 /* Normal search for the next file. */ 00560 const char *name; 00561 while ((name = ReadDirName(dptr->dir_hnd, poffset)) != NULL) { 00562 if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) { 00563 return name; 00564 } 00565 } 00566 return NULL; 00567 }
const char* dptr_ReadDirName | ( | struct dptr_struct * | dptr, | |
long * | poffset, | |||
SMB_STRUCT_STAT * | pst | |||
) |
参照先 connection_struct::case_sensitive・dptr_struct::conn・dptr_struct::did_stat・dptr_struct::dir_hnd・dptr_normal_ReadDirName()・errno・dptr_struct::has_wild・is_visible_file()・smb_Dir::offset・dptr_struct::path・dptr_struct::wcard.
参照元 get_dir_entry()・get_lanman2_dir_entry().
00574 { 00575 SET_STAT_INVALID(*pst); 00576 00577 if (dptr->has_wild) { 00578 return dptr_normal_ReadDirName(dptr, poffset, pst); 00579 } 00580 00581 /* If poffset is -1 then we know we returned this name before and we have 00582 no wildcards. We're at the end of the directory. */ 00583 if (*poffset == END_OF_DIRECTORY_OFFSET) { 00584 return NULL; 00585 } 00586 00587 if (!dptr->did_stat) { 00588 pstring pathreal; 00589 00590 /* We know the stored wcard contains no wildcard characters. See if we can match 00591 with a stat call. If we can't, then set did_stat to true to 00592 ensure we only do this once and keep searching. */ 00593 00594 dptr->did_stat = True; 00595 00596 /* First check if it should be visible. */ 00597 if (!is_visible_file(dptr->conn, dptr->path, dptr->wcard, pst, True)) { 00598 /* This only returns False if the file was found, but 00599 is explicitly not visible. Set us to end of directory, 00600 but return NULL as we know we can't ever find it. */ 00601 dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; 00602 return NULL; 00603 } 00604 00605 if (VALID_STAT(*pst)) { 00606 /* We need to set the underlying dir_hnd offset to -1 also as 00607 this function is usually called with the output from TellDir. */ 00608 dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; 00609 return dptr->wcard; 00610 } 00611 00612 pstrcpy(pathreal,dptr->path); 00613 pstrcat(pathreal,"/"); 00614 pstrcat(pathreal,dptr->wcard); 00615 00616 if (SMB_VFS_STAT(dptr->conn,pathreal,pst) == 0) { 00617 /* We need to set the underlying dir_hnd offset to -1 also as 00618 this function is usually called with the output from TellDir. */ 00619 dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; 00620 return dptr->wcard; 00621 } else { 00622 /* If we get any other error than ENOENT or ENOTDIR 00623 then the file exists we just can't stat it. */ 00624 if (errno != ENOENT && errno != ENOTDIR) { 00625 /* We need to set the underlying dir_hdn offset to -1 also as 00626 this function is usually called with the output from TellDir. */ 00627 dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; 00628 return dptr->wcard; 00629 } 00630 } 00631 00632 /* In case sensitive mode we don't search - we know if it doesn't exist 00633 with a stat we will fail. */ 00634 00635 if (dptr->conn->case_sensitive) { 00636 /* We need to set the underlying dir_hnd offset to -1 also as 00637 this function is usually called with the output from TellDir. */ 00638 dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; 00639 return NULL; 00640 } 00641 } 00642 return dptr_normal_ReadDirName(dptr, poffset, pst); 00643 }
BOOL dptr_SearchDir | ( | struct dptr_struct * | dptr, | |
const char * | name, | |||
long * | poffset, | |||
SMB_STRUCT_STAT * | pst | |||
) |
参照先 dptr_struct::dir_hnd・dptr_struct::has_wild・smb_Dir::offset・SearchDir().
00650 { 00651 SET_STAT_INVALID(*pst); 00652 00653 if (!dptr->has_wild && (dptr->dir_hnd->offset == END_OF_DIRECTORY_OFFSET)) { 00654 /* This is a singleton directory and we're already at the end. */ 00655 *poffset = END_OF_DIRECTORY_OFFSET; 00656 return False; 00657 } 00658 00659 return SearchDir(dptr->dir_hnd, name, poffset); 00660 }
void dptr_DirCacheAdd | ( | struct dptr_struct * | dptr, | |
const char * | name, | |||
long | offset | |||
) |
参照先 dptr_struct::dir_hnd・DirCacheAdd().
00667 { 00668 DirCacheAdd(dptr->dir_hnd, name, offset); 00669 }
BOOL dptr_fill | ( | char * | buf1, | |
unsigned int | key | |||
) |
参照先 buf・dptr_struct::dir_hnd・dptr_get()・TellDir().
参照元 reply_search().
00676 { 00677 unsigned char *buf = (unsigned char *)buf1; 00678 struct dptr_struct *dptr = dptr_get(key, False); 00679 uint32 offset; 00680 if (!dptr) { 00681 DEBUG(1,("filling null dirptr %d\n",key)); 00682 return(False); 00683 } 00684 offset = (uint32)TellDir(dptr->dir_hnd); 00685 DEBUG(6,("fill on key %u dirptr 0x%lx now at %d\n",key, 00686 (long)dptr->dir_hnd,(int)offset)); 00687 buf[0] = key; 00688 SIVAL(buf,1,offset); 00689 return(True); 00690 }
struct dptr_struct* dptr_fetch | ( | char * | buf, | |
int * | num | |||
) |
参照先 dptr_struct::dir_hnd・dptr_get()・dptr_path()・SeekDir().
参照元 reply_fclose()・reply_search().
00697 { 00698 unsigned int key = *(unsigned char *)buf; 00699 struct dptr_struct *dptr = dptr_get(key, False); 00700 uint32 offset; 00701 long seekoff; 00702 00703 if (!dptr) { 00704 DEBUG(3,("fetched null dirptr %d\n",key)); 00705 return(NULL); 00706 } 00707 *num = key; 00708 offset = IVAL(buf,1); 00709 if (offset == (uint32)-1) { 00710 seekoff = END_OF_DIRECTORY_OFFSET; 00711 } else { 00712 seekoff = (long)offset; 00713 } 00714 SeekDir(dptr->dir_hnd,seekoff); 00715 DEBUG(3,("fetching dirptr %d for path %s at offset %d\n", 00716 key,dptr_path(key),(int)seekoff)); 00717 return(dptr); 00718 }
struct dptr_struct* dptr_fetch_lanman2 | ( | int | dptr_num | ) |
参照先 dptr_get()・dptr_path().
00725 { 00726 struct dptr_struct *dptr = dptr_get(dptr_num, False); 00727 00728 if (!dptr) { 00729 DEBUG(3,("fetched null dirptr %d\n",dptr_num)); 00730 return(NULL); 00731 } 00732 DEBUG(3,("fetching dirptr %d for path %s\n",dptr_num,dptr_path(dptr_num))); 00733 return(dptr); 00734 }
BOOL dir_check_ftype | ( | connection_struct * | conn, | |
uint32 | mode, | |||
uint32 | dirtype | |||
) |
参照元 can_delete()・get_dir_entry()・get_lanman2_dir_entry().
00741 { 00742 uint32 mask; 00743 00744 /* Check the "may have" search bits. */ 00745 if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0) 00746 return False; 00747 00748 /* Check the "must have" bits, which are the may have bits shifted eight */ 00749 /* If must have bit is set, the file/dir can not be returned in search unless the matching 00750 file attribute is set */ 00751 mask = ((dirtype >> 8) & (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM)); /* & 0x37 */ 00752 if(mask) { 00753 if((mask & (mode & (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM))) == mask) /* check if matching attribute present */ 00754 return True; 00755 else 00756 return False; 00757 } 00758 00759 return True; 00760 }
static BOOL mangle_mask_match | ( | connection_struct * | conn, | |
fstring | filename, | |||
char * | mask | |||
) | [static] |
参照先 dptr_struct::conn・mangle_map()・mask_match_search()・connection_struct::params.
参照元 get_dir_entry().
00763 { 00764 mangle_map(filename,True,False,conn->params); 00765 return mask_match_search(filename,mask,False); 00766 }
BOOL get_dir_entry | ( | connection_struct * | conn, | |
char * | mask, | |||
uint32 | dirtype, | |||
pstring | fname, | |||
SMB_OFF_T * | size, | |||
uint32 * | mode, | |||
time_t * | date, | |||
BOOL | check_descend | |||
) |
参照先 dptr_struct::conn・dir_check_ftype()・dptr_struct::dir_hnd・DirCacheAdd()・connection_struct::dirpath・connection_struct::dirptr・dptr_ReadDirName()・dptr_TellDir()・errno・mangle_is_8_3()・mangle_map()・mangle_mask_match()・mask_match_search()・connection_struct::params・dptr_struct::path・strerror()・TellDir().
参照元 reply_search().
00774 { 00775 const char *dname; 00776 BOOL found = False; 00777 SMB_STRUCT_STAT sbuf; 00778 pstring path; 00779 pstring pathreal; 00780 pstring filename; 00781 BOOL needslash; 00782 00783 *path = *pathreal = *filename = 0; 00784 00785 needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/'); 00786 00787 if (!conn->dirptr) 00788 return(False); 00789 00790 while (!found) { 00791 long curoff = dptr_TellDir(conn->dirptr); 00792 dname = dptr_ReadDirName(conn->dirptr, &curoff, &sbuf); 00793 00794 DEBUG(6,("readdir on dirptr 0x%lx now at offset %ld\n", 00795 (long)conn->dirptr,TellDir(conn->dirptr->dir_hnd))); 00796 00797 if (dname == NULL) 00798 return(False); 00799 00800 pstrcpy(filename,dname); 00801 00802 /* notice the special *.* handling. This appears to be the only difference 00803 between the wildcard handling in this routine and in the trans2 routines. 00804 see masktest for a demo 00805 */ 00806 if ((strcmp(mask,"*.*") == 0) || 00807 mask_match_search(filename,mask,False) || 00808 mangle_mask_match(conn,filename,mask)) { 00809 00810 if (!mangle_is_8_3(filename, False, conn->params)) 00811 mangle_map(filename,True,False, 00812 conn->params); 00813 00814 pstrcpy(fname,filename); 00815 *path = 0; 00816 pstrcpy(path,conn->dirpath); 00817 if(needslash) 00818 pstrcat(path,"/"); 00819 pstrcpy(pathreal,path); 00820 pstrcat(path,fname); 00821 pstrcat(pathreal,dname); 00822 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn, pathreal, &sbuf)) != 0) { 00823 DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) )); 00824 continue; 00825 } 00826 00827 *mode = dos_mode(conn,pathreal,&sbuf); 00828 00829 if (!dir_check_ftype(conn,*mode,dirtype)) { 00830 DEBUG(5,("[%s] attribs 0x%x didn't match 0x%x\n",filename,(unsigned int)*mode,(unsigned int)dirtype)); 00831 continue; 00832 } 00833 00834 *size = sbuf.st_size; 00835 *date = sbuf.st_mtime; 00836 00837 DEBUG(3,("get_dir_entry mask=[%s] found %s fname=%s\n",mask, pathreal,fname)); 00838 00839 found = True; 00840 00841 DirCacheAdd(conn->dirptr->dir_hnd, dname, curoff); 00842 } 00843 } 00844 00845 return(found); 00846 }
static BOOL user_can_read_file | ( | connection_struct * | conn, | |
char * | name, | |||
SMB_STRUCT_STAT * | pst | |||
) | [static] |
参照先 connection_struct::admin_user・close_file()・dptr_struct::conn・current_user・errno・fd_handle::fd・files_struct::fh・NORMAL_CLOSE・current_user::nt_user_token・open_directory()・open_file_stat()・se_access_check()・status・strerror().
参照元 is_visible_file().
00855 { 00856 SEC_DESC *psd = NULL; 00857 size_t sd_size; 00858 files_struct *fsp; 00859 NTSTATUS status; 00860 uint32 access_granted; 00861 00862 /* 00863 * If user is a member of the Admin group 00864 * we never hide files from them. 00865 */ 00866 00867 if (conn->admin_user) { 00868 return True; 00869 } 00870 00871 /* If we can't stat it does not show it */ 00872 if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) { 00873 DEBUG(10,("user_can_read_file: SMB_VFS_STAT failed for file %s with error %s\n", 00874 name, strerror(errno) )); 00875 return False; 00876 } 00877 00878 /* Pseudo-open the file (note - no fd's created). */ 00879 00880 if(S_ISDIR(pst->st_mode)) { 00881 status = open_directory(conn, name, pst, 00882 READ_CONTROL_ACCESS, 00883 FILE_SHARE_READ|FILE_SHARE_WRITE, 00884 FILE_OPEN, 00885 0, /* no create options. */ 00886 FILE_ATTRIBUTE_DIRECTORY, 00887 NULL, &fsp); 00888 } else { 00889 status = open_file_stat(conn, name, pst, &fsp); 00890 } 00891 00892 if (!NT_STATUS_IS_OK(status)) { 00893 return False; 00894 } 00895 00896 /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ 00897 sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, 00898 (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); 00899 close_file(fsp, NORMAL_CLOSE); 00900 00901 /* No access if SD get failed. */ 00902 if (!sd_size) { 00903 return False; 00904 } 00905 00906 return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA, 00907 &access_granted, &status); 00908 }
static BOOL user_can_write_file | ( | connection_struct * | conn, | |
char * | name, | |||
SMB_STRUCT_STAT * | pst | |||
) | [static] |
参照先 connection_struct::admin_user・close_file()・dptr_struct::conn・current_user・fd_handle::fd・files_struct::fh・NORMAL_CLOSE・current_user::nt_user_token・open_file_ntcreate()・se_access_check()・status.
参照元 is_visible_file().
00918 { 00919 SEC_DESC *psd = NULL; 00920 size_t sd_size; 00921 files_struct *fsp; 00922 int info; 00923 NTSTATUS status; 00924 uint32 access_granted; 00925 00926 /* 00927 * If user is a member of the Admin group 00928 * we never hide files from them. 00929 */ 00930 00931 if (conn->admin_user) { 00932 return True; 00933 } 00934 00935 /* If we can't stat it does not show it */ 00936 if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) { 00937 return False; 00938 } 00939 00940 /* Pseudo-open the file */ 00941 00942 if(S_ISDIR(pst->st_mode)) { 00943 return True; 00944 } else { 00945 status = open_file_ntcreate(conn, name, pst, 00946 FILE_WRITE_ATTRIBUTES, 00947 FILE_SHARE_READ|FILE_SHARE_WRITE, 00948 FILE_OPEN, 00949 0, 00950 FILE_ATTRIBUTE_NORMAL, 00951 INTERNAL_OPEN_ONLY, 00952 &info, &fsp); 00953 } 00954 00955 if (!NT_STATUS_IS_OK(status)) { 00956 return False; 00957 } 00958 00959 /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ 00960 sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, 00961 (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); 00962 close_file(fsp, NORMAL_CLOSE); 00963 00964 /* No access if SD get failed. */ 00965 if (!sd_size) 00966 return False; 00967 00968 return se_access_check(psd, current_user.nt_user_token, FILE_WRITE_DATA, 00969 &access_granted, &status); 00970 }
static BOOL file_is_special | ( | connection_struct * | conn, | |
char * | name, | |||
SMB_STRUCT_STAT * | pst | |||
) | [static] |
参照先 connection_struct::admin_user・dptr_struct::conn.
参照元 is_visible_file().
00977 { 00978 /* 00979 * If user is a member of the Admin group 00980 * we never hide files from them. 00981 */ 00982 00983 if (conn->admin_user) 00984 return False; 00985 00986 /* If we can't stat it does not show it */ 00987 if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) 00988 return True; 00989 00990 if (S_ISREG(pst->st_mode) || S_ISDIR(pst->st_mode) || S_ISLNK(pst->st_mode)) 00991 return False; 00992 00993 return True; 00994 }
BOOL is_visible_file | ( | connection_struct * | conn, | |
const char * | dir_path, | |||
const char * | name, | |||
SMB_STRUCT_STAT * | pst, | |||
BOOL | use_veto | |||
) |
参照先 asprintf()・dptr_struct::conn・file_is_special()・is_msdfs_link()・user_can_read_file()・user_can_write_file().
参照元 can_delete_directory()・dptr_normal_ReadDirName()・dptr_ReadDirName()・recursive_rmdir()・rename_internals()・reply_copy()・rmdir_internals()・unlink_internals().
01001 { 01002 BOOL hide_unreadable = lp_hideunreadable(SNUM(conn)); 01003 BOOL hide_unwriteable = lp_hideunwriteable_files(SNUM(conn)); 01004 BOOL hide_special = lp_hide_special_files(SNUM(conn)); 01005 01006 SET_STAT_INVALID(*pst); 01007 01008 if ((strcmp(".",name) == 0) || (strcmp("..",name) == 0)) { 01009 return True; /* . and .. are always visible. */ 01010 } 01011 01012 /* If it's a vetoed file, pretend it doesn't even exist */ 01013 if (use_veto && IS_VETO_PATH(conn, name)) { 01014 DEBUG(10,("is_visible_file: file %s is vetoed.\n", name )); 01015 return False; 01016 } 01017 01018 if (hide_unreadable || hide_unwriteable || hide_special) { 01019 pstring link_target; 01020 char *entry = NULL; 01021 01022 if (asprintf(&entry, "%s/%s", dir_path, name) == -1) { 01023 return False; 01024 } 01025 01026 /* If it's a dfs symlink, ignore _hide xxxx_ options */ 01027 if (lp_host_msdfs() && 01028 lp_msdfs_root(SNUM(conn)) && 01029 is_msdfs_link(conn, entry, link_target, NULL)) { 01030 SAFE_FREE(entry); 01031 return True; 01032 } 01033 01034 /* Honour _hide unreadable_ option */ 01035 if (hide_unreadable && !user_can_read_file(conn, entry, pst)) { 01036 DEBUG(10,("is_visible_file: file %s is unreadable.\n", entry )); 01037 SAFE_FREE(entry); 01038 return False; 01039 } 01040 /* Honour _hide unwriteable_ option */ 01041 if (hide_unwriteable && !user_can_write_file(conn, entry, pst)) { 01042 DEBUG(10,("is_visible_file: file %s is unwritable.\n", entry )); 01043 SAFE_FREE(entry); 01044 return False; 01045 } 01046 /* Honour _hide_special_ option */ 01047 if (hide_special && file_is_special(conn, entry, pst)) { 01048 DEBUG(10,("is_visible_file: file %s is special.\n", entry )); 01049 SAFE_FREE(entry); 01050 return False; 01051 } 01052 SAFE_FREE(entry); 01053 } 01054 return True; 01055 }
struct smb_Dir* OpenDir | ( | connection_struct * | conn, | |
const char * | name, | |||
const char * | mask, | |||
uint32 | attr | |||
) |
参照先 smb_Dir::conn・smb_Dir::dir・smb_Dir::dir_path・dirhandles_open・errno・smb_Dir::name_cache・smb_Dir::name_cache_size・strerror().
参照元 can_delete_directory()・dptr_create()・dptr_get()・recursive_rmdir()・rename_internals()・reply_copy()・rmdir_internals()・scan_directory()・unlink_internals().
01062 { 01063 struct smb_Dir *dirp = SMB_MALLOC_P(struct smb_Dir); 01064 01065 if (!dirp) { 01066 return NULL; 01067 } 01068 ZERO_STRUCTP(dirp); 01069 01070 dirp->conn = conn; 01071 dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); 01072 01073 dirp->dir_path = SMB_STRDUP(name); 01074 if (!dirp->dir_path) { 01075 goto fail; 01076 } 01077 dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); 01078 if (!dirp->dir) { 01079 DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, strerror(errno) )); 01080 goto fail; 01081 } 01082 01083 if (dirp->name_cache_size) { 01084 dirp->name_cache = SMB_CALLOC_ARRAY(struct name_cache_entry, 01085 dirp->name_cache_size); 01086 if (!dirp->name_cache) { 01087 goto fail; 01088 } 01089 } else { 01090 dirp->name_cache = NULL; 01091 } 01092 01093 dirhandles_open++; 01094 return dirp; 01095 01096 fail: 01097 01098 if (dirp) { 01099 if (dirp->dir) { 01100 SMB_VFS_CLOSEDIR(conn,dirp->dir); 01101 } 01102 SAFE_FREE(dirp->dir_path); 01103 SAFE_FREE(dirp->name_cache); 01104 SAFE_FREE(dirp); 01105 } 01106 return NULL; 01107 }
int CloseDir | ( | struct smb_Dir * | dirp | ) |
参照先 smb_Dir::conn・smb_Dir::dir・smb_Dir::dir_path・dirhandles_open・name_cache_entry::name・smb_Dir::name_cache・smb_Dir::name_cache_size.
参照元 can_delete_directory()・dptr_close_internal()・dptr_CloseDir()・dptr_create()・dptr_idle()・recursive_rmdir()・rename_internals()・reply_copy()・rmdir_internals()・scan_directory()・unlink_internals().
01115 { 01116 int i, ret = 0; 01117 01118 if (dirp->dir) { 01119 ret = SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir); 01120 } 01121 SAFE_FREE(dirp->dir_path); 01122 if (dirp->name_cache) { 01123 for (i = 0; i < dirp->name_cache_size; i++) { 01124 SAFE_FREE(dirp->name_cache[i].name); 01125 } 01126 } 01127 SAFE_FREE(dirp->name_cache); 01128 SAFE_FREE(dirp); 01129 dirhandles_open--; 01130 return ret; 01131 }
const char* ReadDirName | ( | struct smb_Dir * | dirp, | |
long * | poffset | |||
) |
参照先 smb_Dir::conn・smb_Dir::dir・smb_Dir::file_number・smb_Dir::offset・SeekDir()・vfs_readdirname().
参照元 can_delete_directory()・dptr_normal_ReadDirName()・recursive_rmdir()・rename_internals()・reply_copy()・rmdir_internals()・scan_directory()・SearchDir()・unlink_internals().
01139 { 01140 const char *n; 01141 connection_struct *conn = dirp->conn; 01142 01143 /* Cheat to allow . and .. to be the first entries returned. */ 01144 if (((*poffset == START_OF_DIRECTORY_OFFSET) || (*poffset == DOT_DOT_DIRECTORY_OFFSET)) && (dirp->file_number < 2)) { 01145 if (dirp->file_number == 0) { 01146 n = "."; 01147 *poffset = dirp->offset = START_OF_DIRECTORY_OFFSET; 01148 } else { 01149 *poffset = dirp->offset = DOT_DOT_DIRECTORY_OFFSET; 01150 n = ".."; 01151 } 01152 dirp->file_number++; 01153 return n; 01154 } else if (*poffset == END_OF_DIRECTORY_OFFSET) { 01155 *poffset = dirp->offset = END_OF_DIRECTORY_OFFSET; 01156 return NULL; 01157 } else { 01158 /* A real offset, seek to it. */ 01159 SeekDir(dirp, *poffset); 01160 } 01161 01162 while ((n = vfs_readdirname(conn, dirp->dir))) { 01163 /* Ignore . and .. - we've already returned them. */ 01164 if (*n == '.') { 01165 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) { 01166 continue; 01167 } 01168 } 01169 *poffset = dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir); 01170 dirp->file_number++; 01171 return n; 01172 } 01173 *poffset = dirp->offset = END_OF_DIRECTORY_OFFSET; 01174 return NULL; 01175 }
void RewindDir | ( | struct smb_Dir * | dirp, | |
long * | poffset | |||
) |
参照先 smb_Dir::conn・smb_Dir::dir・smb_Dir::file_number・smb_Dir::offset.
参照元 rmdir_internals()・SeekDir().
01182 { 01183 SMB_VFS_REWINDDIR(dirp->conn, dirp->dir); 01184 dirp->file_number = 0; 01185 dirp->offset = START_OF_DIRECTORY_OFFSET; 01186 *poffset = START_OF_DIRECTORY_OFFSET; 01187 }
void SeekDir | ( | struct smb_Dir * | dirp, | |
long | offset | |||
) |
参照先 smb_Dir::conn・smb_Dir::dir・smb_Dir::offset・RewindDir().
参照元 dptr_fetch()・dptr_SeekDir()・ReadDirName()・SearchDir().
01194 { 01195 if (offset != dirp->offset) { 01196 if (offset == START_OF_DIRECTORY_OFFSET) { 01197 RewindDir(dirp, &offset); 01198 /* 01199 * Ok we should really set the file number here 01200 * to 1 to enable ".." to be returned next. Trouble 01201 * is I'm worried about callers using SeekDir(dirp,0) 01202 * as equivalent to RewindDir(). So leave this alone 01203 * for now. 01204 */ 01205 } else if (offset == DOT_DOT_DIRECTORY_OFFSET) { 01206 RewindDir(dirp, &offset); 01207 /* 01208 * Set the file number to 2 - we want to get the first 01209 * real file entry (the one we return after "..") 01210 * on the next ReadDir. 01211 */ 01212 dirp->file_number = 2; 01213 } else if (offset == END_OF_DIRECTORY_OFFSET) { 01214 ; /* Don't seek in this case. */ 01215 } else { 01216 SMB_VFS_SEEKDIR(dirp->conn, dirp->dir, offset); 01217 } 01218 dirp->offset = offset; 01219 } 01220 }
long TellDir | ( | struct smb_Dir * | dirp | ) |
参照先 smb_Dir::offset.
参照元 dptr_fill()・dptr_TellDir()・get_dir_entry().
01227 { 01228 return(dirp->offset); 01229 }
void DirCacheAdd | ( | struct smb_Dir * | dirp, | |
const char * | name, | |||
long | offset | |||
) |
参照先 name_cache_entry::name・smb_Dir::name_cache・smb_Dir::name_cache_index・smb_Dir::name_cache_size・name_cache_entry::offset.
参照元 dptr_DirCacheAdd()・get_dir_entry().
01236 { 01237 struct name_cache_entry *e; 01238 01239 if (!dirp->name_cache_size || !dirp->name_cache) { 01240 return; 01241 } 01242 01243 dirp->name_cache_index = (dirp->name_cache_index+1) % 01244 dirp->name_cache_size; 01245 e = &dirp->name_cache[dirp->name_cache_index]; 01246 SAFE_FREE(e->name); 01247 e->name = SMB_STRDUP(name); 01248 e->offset = offset; 01249 }
参照先 connection_struct::case_sensitive・smb_Dir::conn・smb_Dir::dir・smb_Dir::file_number・name_cache_entry::name・smb_Dir::name_cache・smb_Dir::name_cache_index・smb_Dir::name_cache_size・name_cache_entry::offset・ReadDirName()・SeekDir()・strequal().
参照元 dptr_SearchDir().
01257 { 01258 int i; 01259 const char *entry; 01260 connection_struct *conn = dirp->conn; 01261 01262 /* Search back in the name cache. */ 01263 if (dirp->name_cache_size && dirp->name_cache) { 01264 for (i = dirp->name_cache_index; i >= 0; i--) { 01265 struct name_cache_entry *e = &dirp->name_cache[i]; 01266 if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { 01267 *poffset = e->offset; 01268 SeekDir(dirp, e->offset); 01269 return True; 01270 } 01271 } 01272 for (i = dirp->name_cache_size - 1; i > dirp->name_cache_index; i--) { 01273 struct name_cache_entry *e = &dirp->name_cache[i]; 01274 if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { 01275 *poffset = e->offset; 01276 SeekDir(dirp, e->offset); 01277 return True; 01278 } 01279 } 01280 } 01281 01282 /* Not found in the name cache. Rewind directory and start from scratch. */ 01283 SMB_VFS_REWINDDIR(conn, dirp->dir); 01284 dirp->file_number = 0; 01285 *poffset = START_OF_DIRECTORY_OFFSET; 01286 while ((entry = ReadDirName(dirp, poffset))) { 01287 if (conn->case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) { 01288 return True; 01289 } 01290 } 01291 return False; 01292 }
NTSTATUS can_delete_directory | ( | struct connection_struct * | conn, | |
const char * | dirname | |||
) |
参照先 CloseDir()・smb_Dir::conn・errno・is_visible_file()・map_nt_error_from_unix()・OpenDir()・ReadDirName()・status.
01300 { 01301 NTSTATUS status = NT_STATUS_OK; 01302 long dirpos = 0; 01303 const char *dname; 01304 struct smb_Dir *dir_hnd = OpenDir(conn, dirname, NULL, 0); 01305 01306 if (!dir_hnd) { 01307 return map_nt_error_from_unix(errno); 01308 } 01309 01310 while ((dname = ReadDirName(dir_hnd,&dirpos))) { 01311 SMB_STRUCT_STAT st; 01312 01313 /* Quick check for "." and ".." */ 01314 if (dname[0] == '.') { 01315 if (!dname[1] || (dname[1] == '.' && !dname[2])) { 01316 continue; 01317 } 01318 } 01319 01320 if (!is_visible_file(conn, dirname, dname, &st, True)) { 01321 continue; 01322 } 01323 01324 DEBUG(10,("can_delete_directory: got name %s - can't delete\n", dname )); 01325 status = NT_STATUS_DIRECTORY_NOT_EMPTY; 01326 break; 01327 } 01328 CloseDir(dir_hnd); 01329 01330 return status; 01331 }
struct current_user current_user |
struct dptr_struct* dirptrs [static] |
int dirhandles_open = 0 [static] |