データ構造 | |
struct | vfs_init_function_entry |
関数 | |
static struct vfs_init_function_entry * | vfs_find_backend_entry (const char *name) |
NTSTATUS | smb_register_vfs (int version, const char *name, vfs_op_tuple *vfs_op_tuples) |
static void | vfs_init_default (connection_struct *conn) |
static void | vfs_set_operation (struct vfs_ops *vfs, vfs_op_type which, struct vfs_handle_struct *handle, void *op) |
BOOL | vfs_init_custom (connection_struct *conn, const char *vfs_object) |
void * | vfs_add_fsp_extension_notype (vfs_handle_struct *handle, files_struct *fsp, size_t ext_size) |
void | vfs_remove_fsp_extension (vfs_handle_struct *handle, files_struct *fsp) |
void * | vfs_fetch_fsp_extension (vfs_handle_struct *handle, files_struct *fsp) |
BOOL | smbd_vfs_init (connection_struct *conn) |
BOOL | vfs_directory_exist (connection_struct *conn, const char *dname, SMB_STRUCT_STAT *st) |
BOOL | vfs_object_exist (connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf) |
BOOL | vfs_file_exist (connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf) |
ssize_t | vfs_read_data (files_struct *fsp, char *buf, size_t byte_count) |
ssize_t | vfs_pread_data (files_struct *fsp, char *buf, size_t byte_count, SMB_OFF_T offset) |
ssize_t | vfs_write_data (files_struct *fsp, const char *buffer, size_t N) |
ssize_t | vfs_pwrite_data (files_struct *fsp, const char *buffer, size_t N, SMB_OFF_T offset) |
int | vfs_allocate_file_space (files_struct *fsp, SMB_BIG_UINT len) |
int | vfs_set_filelen (files_struct *fsp, SMB_OFF_T len) |
int | vfs_fill_sparse (files_struct *fsp, SMB_OFF_T len) |
static ssize_t | read_fn (int fd, void *buf, size_t len) |
static ssize_t | write_fn (int fd, const void *buf, size_t len) |
SMB_OFF_T | vfs_transfer_file (files_struct *in, files_struct *out, SMB_OFF_T n) |
char * | vfs_readdirname (connection_struct *conn, void *p) |
int | vfs_ChDir (connection_struct *conn, const char *path) |
static void | array_promote (char *array, int elsize, int element) |
char * | vfs_GetWd (connection_struct *conn, char *path) |
NTSTATUS | reduce_name (connection_struct *conn, const pstring fname) |
変数 | |
static_decl_vfs | |
static struct vfs_init_function_entry * | backends = NULL |
static char * | sparse_buf |
static files_struct * | in_fsp |
static files_struct * | out_fsp |
struct { | |
SMB_DEV_T dev | |
SMB_INO_T inode | |
char * dos_path | |
BOOL valid | |
} | ino_list [MAX_GETWDCACHE] |
BOOL | use_getwd_cache |
static struct vfs_init_function_entry* vfs_find_backend_entry | ( | const char * | name | ) | [static] |
参照先 backends・vfs_init_function_entry::name・vfs_init_function_entry::next.
参照元 smb_register_vfs()・vfs_init_custom().
00046 { 00047 struct vfs_init_function_entry *entry = backends; 00048 00049 while(entry) { 00050 if (strcmp(entry->name, name)==0) return entry; 00051 entry = entry->next; 00052 } 00053 00054 return NULL; 00055 }
NTSTATUS smb_register_vfs | ( | int | version, | |
const char * | name, | |||
vfs_op_tuple * | vfs_op_tuples | |||
) |
参照先 backends・vfs_init_function_entry::name・smb_xstrdup()・vfs_find_backend_entry()・vfs_init_function_entry::vfs_op_tuples.
参照元 vfs_afsacl_init()・vfs_aixacl2_init()・vfs_aixacl_init()・vfs_audit_init()・vfs_cacheprime_init()・vfs_cap_init()・vfs_catia_init()・vfs_commit_init()・vfs_default_init()・vfs_default_quota_init()・vfs_expand_msdfs_init()・vfs_extd_audit_init()・vfs_fake_perms_init()・vfs_full_audit_init()・vfs_gpfs_init()・vfs_hpuxacl_init()・vfs_irixacl_init()・vfs_netatalk_init()・vfs_notify_fam_init()・vfs_posixacl_init()・vfs_prealloc_init()・vfs_readahead_init()・vfs_readonly_init()・vfs_recycle_init()・vfs_shadow_copy_init()・vfs_solarisacl_init()・vfs_tru64acl_init().
00058 { 00059 struct vfs_init_function_entry *entry = backends; 00060 00061 if ((version != SMB_VFS_INTERFACE_VERSION)) { 00062 DEBUG(0, ("Failed to register vfs module.\n" 00063 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n" 00064 "current SMB_VFS_INTERFACE_VERSION is %d.\n" 00065 "Please recompile against the current Samba Version!\n", 00066 version, SMB_VFS_INTERFACE_VERSION)); 00067 return NT_STATUS_OBJECT_TYPE_MISMATCH; 00068 } 00069 00070 if (!name || !name[0] || !vfs_op_tuples) { 00071 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n")); 00072 return NT_STATUS_INVALID_PARAMETER; 00073 } 00074 00075 if (vfs_find_backend_entry(name)) { 00076 DEBUG(0,("VFS module %s already loaded!\n", name)); 00077 return NT_STATUS_OBJECT_NAME_COLLISION; 00078 } 00079 00080 entry = SMB_XMALLOC_P(struct vfs_init_function_entry); 00081 entry->name = smb_xstrdup(name); 00082 entry->vfs_op_tuples = vfs_op_tuples; 00083 00084 DLIST_ADD(backends, entry); 00085 DEBUG(5, ("Successfully added vfs backend '%s'\n", name)); 00086 return NT_STATUS_OK; 00087 }
static void vfs_init_default | ( | connection_struct * | conn | ) | [static] |
参照先 vfs_init_custom().
参照元 smbd_vfs_init().
00094 { 00095 DEBUG(3, ("Initialising default vfs hooks\n")); 00096 vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME); 00097 }
static void vfs_set_operation | ( | struct vfs_ops * | vfs, | |
vfs_op_type | which, | |||
struct vfs_handle_struct * | handle, | |||
void * | op | |||
) | [inline, static] |
参照先 handle・vfs_ops::handles・vfs_ops::ops.
参照元 vfs_init_custom().
00105 { 00106 ((struct vfs_handle_struct **)&vfs->handles)[which] = handle; 00107 ((void **)(void *)&vfs->ops)[which] = op; 00108 }
BOOL vfs_init_custom | ( | connection_struct * | conn, | |
const char * | vfs_object | |||
) |
参照先 backends・handle・connection_struct::mem_ctx・vfs_op_tuple::op・smb_probe_module()・SMB_VFS_LAYER_OPAQUE・smb_xstrdup()・strchr_m()・talloc_strdup()・trim_char()・vfs_op_tuple::type・type・connection_struct::vfs・vfs_find_backend_entry()・connection_struct::vfs_handles・vfs_init_function_entry::vfs_op_tuples・connection_struct::vfs_opaque・vfs_set_operation().
参照元 cmd_load_module()・smbd_vfs_init()・vfs_init_default().
00111 { 00112 vfs_op_tuple *ops; 00113 char *module_name = NULL; 00114 char *module_param = NULL, *p; 00115 int i; 00116 vfs_handle_struct *handle; 00117 struct vfs_init_function_entry *entry; 00118 00119 if (!conn||!vfs_object||!vfs_object[0]) { 00120 DEBUG(0,("vfs_init_custon() called with NULL pointer or emtpy vfs_object!\n")); 00121 return False; 00122 } 00123 00124 if(!backends) { 00125 static_init_vfs; 00126 } 00127 00128 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object)); 00129 00130 module_name = smb_xstrdup(vfs_object); 00131 00132 p = strchr_m(module_name, ':'); 00133 00134 if (p) { 00135 *p = 0; 00136 module_param = p+1; 00137 trim_char(module_param, ' ', ' '); 00138 } 00139 00140 trim_char(module_name, ' ', ' '); 00141 00142 /* First, try to load the module with the new module system */ 00143 if((entry = vfs_find_backend_entry(module_name)) || 00144 (NT_STATUS_IS_OK(smb_probe_module("vfs", module_name)) && 00145 (entry = vfs_find_backend_entry(module_name)))) { 00146 00147 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object)); 00148 00149 if ((ops = entry->vfs_op_tuples) == NULL) { 00150 DEBUG(0, ("entry->vfs_op_tuples==NULL for [%s] failed\n", vfs_object)); 00151 SAFE_FREE(module_name); 00152 return False; 00153 } 00154 } else { 00155 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object)); 00156 SAFE_FREE(module_name); 00157 return False; 00158 } 00159 00160 handle = TALLOC_ZERO_P(conn->mem_ctx,vfs_handle_struct); 00161 if (!handle) { 00162 DEBUG(0,("TALLOC_ZERO() failed!\n")); 00163 SAFE_FREE(module_name); 00164 return False; 00165 } 00166 memcpy(&handle->vfs_next, &conn->vfs, sizeof(struct vfs_ops)); 00167 handle->conn = conn; 00168 if (module_param) { 00169 handle->param = talloc_strdup(conn->mem_ctx, module_param); 00170 } 00171 DLIST_ADD(conn->vfs_handles, handle); 00172 00173 for(i=0; ops[i].op != NULL; i++) { 00174 DEBUG(5, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer)); 00175 if(ops[i].layer == SMB_VFS_LAYER_OPAQUE) { 00176 /* If this operation was already made opaque by different module, it 00177 * will be overridden here. 00178 */ 00179 DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object)); 00180 vfs_set_operation(&conn->vfs_opaque, ops[i].type, handle, ops[i].op); 00181 } 00182 /* Change current VFS disposition*/ 00183 DEBUGADD(5, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object)); 00184 vfs_set_operation(&conn->vfs, ops[i].type, handle, ops[i].op); 00185 } 00186 00187 SAFE_FREE(module_name); 00188 return True; 00189 }
void* vfs_add_fsp_extension_notype | ( | vfs_handle_struct * | handle, | |
files_struct * | fsp, | |||
size_t | ext_size | |||
) |
参照先 handle・vfs_fsp_data::next・vfs_fsp_data::owner・files_struct::vfs_extension・vfs_fetch_fsp_extension().
00200 { 00201 struct vfs_fsp_data *ext; 00202 void * ext_data; 00203 00204 /* Prevent VFS modules adding multiple extensions. */ 00205 if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) { 00206 return ext_data; 00207 } 00208 00209 ext = (struct vfs_fsp_data *)TALLOC_ZERO( 00210 handle->conn->mem_ctx, sizeof(struct vfs_fsp_data) + ext_size); 00211 if (ext == NULL) { 00212 return NULL; 00213 } 00214 00215 ext->owner = handle; 00216 ext->next = fsp->vfs_extension; 00217 fsp->vfs_extension = ext; 00218 return EXT_DATA_AREA(ext); 00219 }
void vfs_remove_fsp_extension | ( | vfs_handle_struct * | handle, | |
files_struct * | fsp | |||
) |
参照先 handle・vfs_fsp_data::next・vfs_fsp_data::owner・files_struct::vfs_extension.
00222 { 00223 struct vfs_fsp_data *curr; 00224 struct vfs_fsp_data *prev; 00225 00226 for (curr = fsp->vfs_extension, prev = NULL; 00227 curr; 00228 prev = curr, curr = curr->next) { 00229 if (curr->owner == handle) { 00230 if (prev) { 00231 prev->next = curr->next; 00232 } else { 00233 fsp->vfs_extension = curr->next; 00234 } 00235 TALLOC_FREE(curr); 00236 return; 00237 } 00238 } 00239 }
void* vfs_fetch_fsp_extension | ( | vfs_handle_struct * | handle, | |
files_struct * | fsp | |||
) |
参照先 handle・vfs_fsp_data::next・vfs_fsp_data::owner・files_struct::vfs_extension.
参照元 vfs_add_fsp_extension_notype().
00242 { 00243 struct vfs_fsp_data *head; 00244 00245 for (head = fsp->vfs_extension; head; head = head->next) { 00246 if (head->owner == handle) { 00247 return EXT_DATA_AREA(head); 00248 } 00249 } 00250 00251 return NULL; 00252 }
BOOL smbd_vfs_init | ( | connection_struct * | conn | ) |
参照先 vfs_init_custom()・vfs_init_default().
参照元 create_conn_struct()・get_nt_acl_no_snum()・main().
00261 { 00262 const char **vfs_objects; 00263 unsigned int i = 0; 00264 int j = 0; 00265 00266 /* Normal share - initialise with disk access functions */ 00267 vfs_init_default(conn); 00268 vfs_objects = lp_vfs_objects(SNUM(conn)); 00269 00270 /* Override VFS functions if 'vfs object' was not specified*/ 00271 if (!vfs_objects || !vfs_objects[0]) 00272 return True; 00273 00274 for (i=0; vfs_objects[i] ;) { 00275 i++; 00276 } 00277 00278 for (j=i-1; j >= 0; j--) { 00279 if (!vfs_init_custom(conn, vfs_objects[j])) { 00280 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j])); 00281 return False; 00282 } 00283 } 00284 return True; 00285 }
BOOL vfs_directory_exist | ( | connection_struct * | conn, | |
const char * | dname, | |||
SMB_STRUCT_STAT * | st | |||
) |
参照先 errno.
参照元 reply_setdir().
00292 { 00293 SMB_STRUCT_STAT st2; 00294 BOOL ret; 00295 00296 if (!st) 00297 st = &st2; 00298 00299 if (SMB_VFS_STAT(conn,dname,st) != 0) 00300 return(False); 00301 00302 ret = S_ISDIR(st->st_mode); 00303 if(!ret) 00304 errno = ENOTDIR; 00305 00306 return ret; 00307 }
BOOL vfs_object_exist | ( | connection_struct * | conn, | |
const char * | fname, | |||
SMB_STRUCT_STAT * | sbuf | |||
) |
参照元 rename_internals()・rename_internals_fsp().
00314 { 00315 SMB_STRUCT_STAT st; 00316 00317 if (!sbuf) 00318 sbuf = &st; 00319 00320 ZERO_STRUCTP(sbuf); 00321 00322 if (SMB_VFS_STAT(conn,fname,sbuf) == -1) 00323 return(False); 00324 return True; 00325 }
BOOL vfs_file_exist | ( | connection_struct * | conn, | |
const char * | fname, | |||
SMB_STRUCT_STAT * | sbuf | |||
) |
参照元 copy_file()・get_correct_cversion()・rename_internals().
00332 { 00333 SMB_STRUCT_STAT st; 00334 00335 if (!sbuf) 00336 sbuf = &st; 00337 00338 ZERO_STRUCTP(sbuf); 00339 00340 if (SMB_VFS_STAT(conn,fname,sbuf) == -1) 00341 return False; 00342 return(S_ISREG(sbuf->st_mode)); 00343 }
ssize_t vfs_read_data | ( | files_struct * | fsp, | |
char * | buf, | |||
size_t | byte_count | |||
) |
参照先 errno・fd_handle::fd・files_struct::fh・total.
参照元 get_file_version().
00350 { 00351 size_t total=0; 00352 00353 while (total < byte_count) 00354 { 00355 ssize_t ret = SMB_VFS_READ(fsp, fsp->fh->fd, buf + total, 00356 byte_count - total); 00357 00358 if (ret == 0) return total; 00359 if (ret == -1) { 00360 if (errno == EINTR) 00361 continue; 00362 else 00363 return -1; 00364 } 00365 total += ret; 00366 } 00367 return (ssize_t)total; 00368 }
ssize_t vfs_pread_data | ( | files_struct * | fsp, | |
char * | buf, | |||
size_t | byte_count, | |||
SMB_OFF_T | offset | |||
) |
参照先 errno・fd_handle::fd・files_struct::fh・total.
00372 { 00373 size_t total=0; 00374 00375 while (total < byte_count) 00376 { 00377 ssize_t ret = SMB_VFS_PREAD(fsp, fsp->fh->fd, buf + total, 00378 byte_count - total, offset + total); 00379 00380 if (ret == 0) return total; 00381 if (ret == -1) { 00382 if (errno == EINTR) 00383 continue; 00384 else 00385 return -1; 00386 } 00387 total += ret; 00388 } 00389 return (ssize_t)total; 00390 }
ssize_t vfs_write_data | ( | files_struct * | fsp, | |
const char * | buffer, | |||
size_t | N | |||
) |
参照先 fd_handle::fd・files_struct::fh・total.
参照元 real_write_file().
00397 { 00398 size_t total=0; 00399 ssize_t ret; 00400 00401 while (total < N) { 00402 ret = SMB_VFS_WRITE(fsp,fsp->fh->fd,buffer + total,N - total); 00403 00404 if (ret == -1) 00405 return -1; 00406 if (ret == 0) 00407 return total; 00408 00409 total += ret; 00410 } 00411 return (ssize_t)total; 00412 }
ssize_t vfs_pwrite_data | ( | files_struct * | fsp, | |
const char * | buffer, | |||
size_t | N, | |||
SMB_OFF_T | offset | |||
) |
参照先 fd_handle::fd・files_struct::fh・total.
参照元 real_write_file().
00416 { 00417 size_t total=0; 00418 ssize_t ret; 00419 00420 while (total < N) { 00421 ret = SMB_VFS_PWRITE(fsp, fsp->fh->fd, buffer + total, 00422 N - total, offset + total); 00423 00424 if (ret == -1) 00425 return -1; 00426 if (ret == 0) 00427 return total; 00428 00429 total += ret; 00430 } 00431 return (ssize_t)total; 00432 }
int vfs_allocate_file_space | ( | files_struct * | fsp, | |
SMB_BIG_UINT | len | |||
) |
参照先 files_struct::conn・errno・fd_handle::fd・files_struct::fh・flush_write_cache()・files_struct::fsp_name・get_dfree_info()・release_level_2_oplocks_on_change()・set_filelen_write_cache().
参照元 call_nt_transact_create()・call_trans2open()・reply_ntcreate_and_X()・reply_open_and_X()・reply_write()・smb_set_file_allocation_info().
00440 { 00441 int ret; 00442 SMB_STRUCT_STAT st; 00443 connection_struct *conn = fsp->conn; 00444 SMB_BIG_UINT space_avail; 00445 SMB_BIG_UINT bsize,dfree,dsize; 00446 00447 release_level_2_oplocks_on_change(fsp); 00448 00449 /* 00450 * Actually try and commit the space on disk.... 00451 */ 00452 00453 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n", fsp->fsp_name, (double)len )); 00454 00455 if (((SMB_OFF_T)len) < 0) { 00456 DEBUG(0,("vfs_allocate_file_space: %s negative len requested.\n", fsp->fsp_name )); 00457 errno = EINVAL; 00458 return -1; 00459 } 00460 00461 ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st); 00462 if (ret == -1) 00463 return ret; 00464 00465 if (len == (SMB_BIG_UINT)st.st_size) 00466 return 0; 00467 00468 if (len < (SMB_BIG_UINT)st.st_size) { 00469 /* Shrink - use ftruncate. */ 00470 00471 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current size %.0f\n", 00472 fsp->fsp_name, (double)st.st_size )); 00473 00474 flush_write_cache(fsp, SIZECHANGE_FLUSH); 00475 if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, (SMB_OFF_T)len)) != -1) { 00476 set_filelen_write_cache(fsp, len); 00477 } 00478 return ret; 00479 } 00480 00481 /* Grow - we need to test if we have enough space. */ 00482 00483 if (!lp_strict_allocate(SNUM(fsp->conn))) 00484 return 0; 00485 00486 len -= st.st_size; 00487 len /= 1024; /* Len is now number of 1k blocks needed. */ 00488 space_avail = get_dfree_info(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize); 00489 if (space_avail == (SMB_BIG_UINT)-1) { 00490 return -1; 00491 } 00492 00493 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %.0f, space avail = %.0f\n", 00494 fsp->fsp_name, (double)st.st_size, (double)len, (double)space_avail )); 00495 00496 if (len > space_avail) { 00497 errno = ENOSPC; 00498 return -1; 00499 } 00500 00501 return 0; 00502 }
int vfs_set_filelen | ( | files_struct * | fsp, | |
SMB_OFF_T | len | |||
) |
参照先 files_struct::conn・fd_handle::fd・files_struct::fh・flush_write_cache()・files_struct::fsp_name・notify_fname()・release_level_2_oplocks_on_change()・set_filelen_write_cache().
参照元 reply_open_and_X()・reply_write()・smb_set_file_size().
00511 { 00512 int ret; 00513 00514 release_level_2_oplocks_on_change(fsp); 00515 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len)); 00516 flush_write_cache(fsp, SIZECHANGE_FLUSH); 00517 if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, len)) != -1) { 00518 set_filelen_write_cache(fsp, len); 00519 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED, 00520 FILE_NOTIFY_CHANGE_SIZE 00521 | FILE_NOTIFY_CHANGE_ATTRIBUTES, 00522 fsp->fsp_name); 00523 } 00524 00525 return ret; 00526 }
int vfs_fill_sparse | ( | files_struct * | fsp, | |
SMB_OFF_T | len | |||
) |
参照先 errno・fd_handle::fd・files_struct::fh・flush_write_cache()・files_struct::fsp_name・release_level_2_oplocks_on_change()・set_filelen_write_cache()・sparse_buf・strerror()・total.
参照元 real_write_file().
00539 { 00540 int ret; 00541 SMB_STRUCT_STAT st; 00542 SMB_OFF_T offset; 00543 size_t total; 00544 size_t num_to_write; 00545 ssize_t pwrite_ret; 00546 00547 release_level_2_oplocks_on_change(fsp); 00548 ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st); 00549 if (ret == -1) { 00550 return ret; 00551 } 00552 00553 if (len <= st.st_size) { 00554 return 0; 00555 } 00556 00557 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to len %.0f (%.0f bytes)\n", 00558 fsp->fsp_name, (double)st.st_size, (double)len, (double)(len - st.st_size))); 00559 00560 flush_write_cache(fsp, SIZECHANGE_FLUSH); 00561 00562 if (!sparse_buf) { 00563 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE); 00564 if (!sparse_buf) { 00565 errno = ENOMEM; 00566 return -1; 00567 } 00568 } 00569 00570 offset = st.st_size; 00571 num_to_write = len - st.st_size; 00572 total = 0; 00573 00574 while (total < num_to_write) { 00575 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (num_to_write - total)); 00576 00577 pwrite_ret = SMB_VFS_PWRITE(fsp, fsp->fh->fd, sparse_buf, curr_write_size, offset + total); 00578 if (pwrite_ret == -1) { 00579 DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file %s failed with error %s\n", 00580 fsp->fsp_name, strerror(errno) )); 00581 return -1; 00582 } 00583 if (pwrite_ret == 0) { 00584 return 0; 00585 } 00586 00587 total += pwrite_ret; 00588 } 00589 00590 set_filelen_write_cache(fsp, len); 00591 return 0; 00592 }
static ssize_t read_fn | ( | int | fd, | |
void * | buf, | |||
size_t | len | |||
) | [static] |
static ssize_t write_fn | ( | int | fd, | |
const void * | buf, | |||
size_t | len | |||
) | [static] |
SMB_OFF_T vfs_transfer_file | ( | files_struct * | in, | |
files_struct * | out, | |||
SMB_OFF_T | n | |||
) |
参照先 fd_handle::fd・files_struct::fh・in_fsp・out_fsp・read_fn()・transfer_file_internal()・write_fn().
参照元 copy_file()・copy_internals().
00612 { 00613 in_fsp = in; 00614 out_fsp = out; 00615 00616 return transfer_file_internal(in_fsp->fh->fd, out_fsp->fh->fd, n, read_fn, write_fn); 00617 }
char* vfs_readdirname | ( | connection_struct * | conn, | |
void * | p | |||
) |
参照先 telldir().
参照元 form_junctions()・ReadDirName().
00624 { 00625 SMB_STRUCT_DIRENT *ptr= NULL; 00626 char *dname; 00627 00628 if (!p) 00629 return(NULL); 00630 00631 ptr = SMB_VFS_READDIR(conn, (DIR *)p); 00632 if (!ptr) 00633 return(NULL); 00634 00635 dname = ptr->d_name; 00636 00637 #ifdef NEXT2 00638 if (telldir(p) < 0) 00639 return(NULL); 00640 #endif 00641 00642 #ifdef HAVE_BROKEN_READDIR_NAME 00643 /* using /usr/ucb/cc is BAD */ 00644 dname = dname - 2; 00645 #endif 00646 00647 return(dname); 00648 }
int vfs_ChDir | ( | connection_struct * | conn, | |
const char * | path | |||
) |
参照先 strcsequal().
参照元 _dfs_Add()・_dfs_Enum()・_dfs_GetInfo()・_dfs_Remove()・change_dir_owner_to_parent()・close_cnum()・create_conn_struct()・make_connection_with_chdir()・set_current_service()・setup_dfs_referral().
00655 { 00656 int res; 00657 static pstring LastDir=""; 00658 00659 if (strcsequal(path,".")) 00660 return(0); 00661 00662 if (*path == '/' && strcsequal(LastDir,path)) 00663 return(0); 00664 00665 DEBUG(4,("vfs_ChDir to %s\n",path)); 00666 00667 res = SMB_VFS_CHDIR(conn,path); 00668 if (!res) 00669 pstrcpy(LastDir,path); 00670 return(res); 00671 }
static void array_promote | ( | char * | array, | |
int | elsize, | |||
int | element | |||
) | [static] |
参照元 vfs_GetWd().
00690 { 00691 char *p; 00692 if (element == 0) 00693 return; 00694 00695 p = (char *)SMB_MALLOC(elsize); 00696 00697 if (!p) { 00698 DEBUG(5,("array_promote: malloc fail\n")); 00699 return; 00700 } 00701 00702 memcpy(p,array + element * elsize, elsize); 00703 memmove(array + elsize,array,elsize*element); 00704 memcpy(array,p,elsize); 00705 SAFE_FREE(p); 00706 }
char* vfs_GetWd | ( | connection_struct * | conn, | |
char * | path | |||
) |
参照先 array_promote()・dos_path・errno・ino_list・strerror()・string_set()・use_getwd_cache・valid.
参照元 change_dir_owner_to_parent().
00715 { 00716 pstring s; 00717 static BOOL getwd_cache_init = False; 00718 SMB_STRUCT_STAT st, st2; 00719 int i; 00720 00721 *s = 0; 00722 00723 if (!use_getwd_cache) 00724 return(SMB_VFS_GETWD(conn,path)); 00725 00726 /* init the cache */ 00727 if (!getwd_cache_init) { 00728 getwd_cache_init = True; 00729 for (i=0;i<MAX_GETWDCACHE;i++) { 00730 string_set(&ino_list[i].dos_path,""); 00731 ino_list[i].valid = False; 00732 } 00733 } 00734 00735 /* Get the inode of the current directory, if this doesn't work we're 00736 in trouble :-) */ 00737 00738 if (SMB_VFS_STAT(conn, ".",&st) == -1) { 00739 /* Known to fail for root: the directory may be 00740 * NFS-mounted and exported with root_squash (so has no root access). */ 00741 DEBUG(1,("vfs_GetWd: couldn't stat \".\" path=%s error %s (NFS problem ?)\n", path, strerror(errno) )); 00742 return(SMB_VFS_GETWD(conn,path)); 00743 } 00744 00745 00746 for (i=0; i<MAX_GETWDCACHE; i++) { 00747 if (ino_list[i].valid) { 00748 00749 /* If we have found an entry with a matching inode and dev number 00750 then find the inode number for the directory in the cached string. 00751 If this agrees with that returned by the stat for the current 00752 directory then all is o.k. (but make sure it is a directory all 00753 the same...) */ 00754 00755 if (st.st_ino == ino_list[i].inode && st.st_dev == ino_list[i].dev) { 00756 if (SMB_VFS_STAT(conn,ino_list[i].dos_path,&st2) == 0) { 00757 if (st.st_ino == st2.st_ino && st.st_dev == st2.st_dev && 00758 (st2.st_mode & S_IFMT) == S_IFDIR) { 00759 pstrcpy (path, ino_list[i].dos_path); 00760 00761 /* promote it for future use */ 00762 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i); 00763 return (path); 00764 } else { 00765 /* If the inode is different then something's changed, 00766 scrub the entry and start from scratch. */ 00767 ino_list[i].valid = False; 00768 } 00769 } 00770 } 00771 } 00772 } 00773 00774 /* We don't have the information to hand so rely on traditional methods. 00775 The very slow getcwd, which spawns a process on some systems, or the 00776 not quite so bad getwd. */ 00777 00778 if (!SMB_VFS_GETWD(conn,s)) { 00779 DEBUG(0,("vfs_GetWd: SMB_VFS_GETWD call failed, errno %s\n",strerror(errno))); 00780 return (NULL); 00781 } 00782 00783 pstrcpy(path,s); 00784 00785 DEBUG(5,("vfs_GetWd %s, inode %.0f, dev %.0f\n",s,(double)st.st_ino,(double)st.st_dev)); 00786 00787 /* add it to the cache */ 00788 i = MAX_GETWDCACHE - 1; 00789 string_set(&ino_list[i].dos_path,s); 00790 ino_list[i].dev = st.st_dev; 00791 ino_list[i].inode = st.st_ino; 00792 ino_list[i].valid = True; 00793 00794 /* put it at the top of the list */ 00795 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i); 00796 00797 return (path); 00798 }
NTSTATUS reduce_name | ( | connection_struct * | conn, | |
const pstring | fname | |||
) |
参照先 connection_struct::connectpath・errno・map_nt_error_from_unix()・strrchr_m().
参照元 check_name()・copy_internals()・hardlink_internals().
00806 { 00807 #ifdef REALPATH_TAKES_NULL 00808 BOOL free_resolved_name = True; 00809 #else 00810 #ifdef PATH_MAX 00811 char resolved_name_buf[PATH_MAX+1]; 00812 #else 00813 pstring resolved_name_buf; 00814 #endif 00815 BOOL free_resolved_name = False; 00816 #endif 00817 char *resolved_name = NULL; 00818 size_t con_path_len = strlen(conn->connectpath); 00819 char *p = NULL; 00820 00821 DEBUG(3,("reduce_name [%s] [%s]\n", fname, conn->connectpath)); 00822 00823 #ifdef REALPATH_TAKES_NULL 00824 resolved_name = SMB_VFS_REALPATH(conn,fname,NULL); 00825 #else 00826 resolved_name = SMB_VFS_REALPATH(conn,fname,resolved_name_buf); 00827 #endif 00828 00829 if (!resolved_name) { 00830 switch (errno) { 00831 case ENOTDIR: 00832 DEBUG(3,("reduce_name: Component not a directory in getting realpath for %s\n", fname)); 00833 return map_nt_error_from_unix(errno); 00834 case ENOENT: 00835 { 00836 pstring tmp_fname; 00837 fstring last_component; 00838 /* Last component didn't exist. Remove it and try and canonicalise the directory. */ 00839 00840 pstrcpy(tmp_fname, fname); 00841 p = strrchr_m(tmp_fname, '/'); 00842 if (p) { 00843 *p++ = '\0'; 00844 fstrcpy(last_component, p); 00845 } else { 00846 fstrcpy(last_component, tmp_fname); 00847 pstrcpy(tmp_fname, "."); 00848 } 00849 00850 #ifdef REALPATH_TAKES_NULL 00851 resolved_name = SMB_VFS_REALPATH(conn,tmp_fname,NULL); 00852 #else 00853 resolved_name = SMB_VFS_REALPATH(conn,tmp_fname,resolved_name_buf); 00854 #endif 00855 if (!resolved_name) { 00856 DEBUG(3,("reduce_name: couldn't get realpath for %s\n", fname)); 00857 return map_nt_error_from_unix(errno); 00858 } 00859 pstrcpy(tmp_fname, resolved_name); 00860 pstrcat(tmp_fname, "/"); 00861 pstrcat(tmp_fname, last_component); 00862 #ifdef REALPATH_TAKES_NULL 00863 SAFE_FREE(resolved_name); 00864 resolved_name = SMB_STRDUP(tmp_fname); 00865 if (!resolved_name) { 00866 DEBUG(0,("reduce_name: malloc fail for %s\n", tmp_fname)); 00867 return NT_STATUS_NO_MEMORY; 00868 } 00869 #else 00870 #ifdef PATH_MAX 00871 safe_strcpy(resolved_name_buf, tmp_fname, PATH_MAX); 00872 #else 00873 pstrcpy(resolved_name_buf, tmp_fname); 00874 #endif 00875 resolved_name = resolved_name_buf; 00876 #endif 00877 break; 00878 } 00879 default: 00880 DEBUG(1,("reduce_name: couldn't get realpath for %s\n", fname)); 00881 return map_nt_error_from_unix(errno); 00882 } 00883 } 00884 00885 DEBUG(10,("reduce_name realpath [%s] -> [%s]\n", fname, resolved_name)); 00886 00887 if (*resolved_name != '/') { 00888 DEBUG(0,("reduce_name: realpath doesn't return absolute paths !\n")); 00889 if (free_resolved_name) { 00890 SAFE_FREE(resolved_name); 00891 } 00892 return NT_STATUS_OBJECT_NAME_INVALID; 00893 } 00894 00895 /* Check for widelinks allowed. */ 00896 if (!lp_widelinks(SNUM(conn)) && (strncmp(conn->connectpath, resolved_name, con_path_len) != 0)) { 00897 DEBUG(2, ("reduce_name: Bad access attempt: %s is a symlink outside the share path", fname)); 00898 if (free_resolved_name) { 00899 SAFE_FREE(resolved_name); 00900 } 00901 return NT_STATUS_ACCESS_DENIED; 00902 } 00903 00904 /* Check if we are allowing users to follow symlinks */ 00905 /* Patch from David Clerc <David.Clerc@cui.unige.ch> 00906 University of Geneva */ 00907 00908 #ifdef S_ISLNK 00909 if (!lp_symlinks(SNUM(conn))) { 00910 SMB_STRUCT_STAT statbuf; 00911 if ( (SMB_VFS_LSTAT(conn,fname,&statbuf) != -1) && 00912 (S_ISLNK(statbuf.st_mode)) ) { 00913 if (free_resolved_name) { 00914 SAFE_FREE(resolved_name); 00915 } 00916 DEBUG(3,("reduce_name: denied: file path name %s is a symlink\n",resolved_name)); 00917 return NT_STATUS_ACCESS_DENIED; 00918 } 00919 } 00920 #endif 00921 00922 DEBUG(3,("reduce_name: %s reduced to %s\n", fname, resolved_name)); 00923 if (free_resolved_name) { 00924 SAFE_FREE(resolved_name); 00925 } 00926 return NT_STATUS_OK; 00927 }
struct vfs_init_function_entry* backends = NULL [static] |
char* sparse_buf [static] |
files_struct* in_fsp [static] |
files_struct* out_fsp [static] |
SMB_DEV_T dev |
SMB_INO_T inode |
char* dos_path |
struct { ... } ino_list[MAX_GETWDCACHE] [static] |
参照元 vfs_GetWd().