Changeset 77 for trunk/samba/source/smbd/dir.c
- Timestamp:
- Sep 30, 2007, 3:42:50 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/samba/source/smbd/dir.c
r71 r77 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 Directory handling routines 4 4 Copyright (C) Andrew Tridgell 1992-1998 5 5 Copyright (C) Jeremy Allison 2007 6 6 7 This program is free software; you can redistribute it and/or modify 7 8 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2of the License, or9 the Free Software Foundation; either version 3 of the License, or 9 10 (at your option) any later version. 10 11 11 12 This program is distributed in the hope that it will be useful, 12 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 15 GNU General Public License for more details. 15 16 16 17 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 19 */ 20 20 … … 74 74 ****************************************************************************/ 75 75 76 void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T size,uint32 mode,time_t date, BOOL uc) 77 { 76 BOOL make_dir_struct(TALLOC_CTX *ctx, 77 char *buf, 78 const char *mask, 79 const char *fname, 80 SMB_OFF_T size, 81 uint32 mode, 82 time_t date, 83 BOOL uc) 84 { 78 85 char *p; 79 pstring mask2; 80 81 pstrcpy(mask2,mask); 82 83 if ((mode & aDIR) != 0) 86 char *mask2 = talloc_strdup(ctx, mask); 87 88 if (!mask2) { 89 return False; 90 } 91 92 if ((mode & aDIR) != 0) { 84 93 size = 0; 94 } 85 95 86 96 memset(buf+1,' ',11); … … 90 100 push_ascii(buf+9,p+1,3, 0); 91 101 *p = '.'; 92 } else 102 } else { 93 103 push_ascii(buf+1,mask2,11, 0); 104 } 94 105 95 106 memset(buf+21,'\0',DIR_STRUCT_SIZE-21); … … 102 113 push_ascii(buf+30,fname,12, uc ? STR_UPPER : 0); 103 114 DEBUG(8,("put name [%s] from [%s] into dir struct\n",buf+30, fname)); 115 return True; 104 116 } 105 117 … … 240 252 DLIST_REMOVE(dirptrs, dptr); 241 253 242 /* 254 /* 243 255 * Free the dnum in the bitmap. Remember the dnum value is always 244 256 * biased by one with respect to the bitmap. … … 382 394 ****************************************************************************/ 383 395 384 NTSTATUS dptr_create(connection_struct *conn, pstringpath, BOOL old_handle, BOOL expect_close,uint16 spid,396 NTSTATUS dptr_create(connection_struct *conn, const char *path, BOOL old_handle, BOOL expect_close,uint16 spid, 385 397 const char *wcard, BOOL wcard_has_wild, uint32 attr, struct dptr_struct **dptr_ret) 386 398 { 387 399 struct dptr_struct *dptr = NULL; 388 400 struct smb_Dir *dir_hnd; 389 const char *dir2;390 401 NTSTATUS status; 391 402 … … 401 412 } 402 413 403 /* use a const pointer from here on */ 404 dir2 = path; 405 if (!*dir2) 406 dir2 = "."; 407 408 dir_hnd = OpenDir(conn, dir2, wcard, attr); 414 dir_hnd = OpenDir(conn, path, wcard, attr); 409 415 if (!dir_hnd) { 410 416 return map_nt_error_from_unix(errno); 411 417 } 412 418 413 string_set(&conn->dirpath, dir2);419 string_set(&conn->dirpath,path); 414 420 415 421 if (dirhandles_open >= MAX_OPEN_DIRECTORIES) { … … 490 496 dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */ 491 497 492 string_set(&dptr->path, dir2);498 string_set(&dptr->path,path); 493 499 dptr->conn = conn; 494 500 dptr->dir_hnd = dir_hnd; … … 571 577 ****************************************************************************/ 572 578 573 const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT_STAT *pst) 579 const char *dptr_ReadDirName(TALLOC_CTX *ctx, 580 struct dptr_struct *dptr, 581 long *poffset, 582 SMB_STRUCT_STAT *pst) 574 583 { 575 584 SET_STAT_INVALID(*pst); … … 586 595 587 596 if (!dptr->did_stat) { 588 pstring pathreal;597 char *pathreal = NULL; 589 598 590 599 /* We know the stored wcard contains no wildcard characters. See if we can match … … 610 619 } 611 620 612 pstrcpy(pathreal,dptr->path); 613 pstrcat(pathreal,"/"); 614 pstrcat(pathreal,dptr->wcard); 621 pathreal = talloc_asprintf(ctx, 622 "%s/%s", 623 dptr->path, 624 dptr->wcard); 625 if (!pathreal) { 626 return NULL; 627 } 615 628 616 629 if (SMB_VFS_STAT(dptr->conn,pathreal,pst) == 0) { … … 618 631 this function is usually called with the output from TellDir. */ 619 632 dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; 633 TALLOC_FREE(pathreal); 620 634 return dptr->wcard; 621 635 } else { … … 626 640 this function is usually called with the output from TellDir. */ 627 641 dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; 642 TALLOC_FREE(pathreal); 628 643 return dptr->wcard; 629 644 } 630 645 } 646 647 TALLOC_FREE(pathreal); 631 648 632 649 /* In case sensitive mode we don't search - we know if it doesn't exist … … 760 777 } 761 778 762 static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *mask) 763 { 764 mangle_map(filename,True,False,conn->params); 765 return mask_match_search(filename,mask,False); 779 static BOOL mangle_mask_match(connection_struct *conn, 780 const char *filename, 781 const char *mask) 782 { 783 char mname[13]; 784 785 if (!name_to_8_3(filename,mname,False,conn->params)) { 786 return False; 787 } 788 return mask_match_search(mname,mask,False); 766 789 } 767 790 … … 770 793 ****************************************************************************/ 771 794 772 BOOL get_dir_entry(connection_struct *conn,char *mask,uint32 dirtype, pstring fname, 773 SMB_OFF_T *size,uint32 *mode,time_t *date,BOOL check_descend) 774 { 775 const char *dname; 795 BOOL get_dir_entry(TALLOC_CTX *ctx, 796 connection_struct *conn, 797 const char *mask, 798 uint32 dirtype, 799 char **pp_fname_out, 800 SMB_OFF_T *size, 801 uint32 *mode, 802 time_t *date, 803 BOOL check_descend) 804 { 805 const char *dname = NULL; 776 806 BOOL found = False; 777 807 SMB_STRUCT_STAT sbuf; 778 pstring path; 779 pstring pathreal; 780 pstring filename; 808 char *pathreal = NULL; 809 const char *filename = NULL; 781 810 BOOL needslash; 782 811 783 *p ath = *pathreal = *filename = 0;812 *pp_fname_out = NULL; 784 813 785 814 needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/'); 786 815 787 if (!conn->dirptr) 816 if (!conn->dirptr) { 788 817 return(False); 818 } 789 819 790 820 while (!found) { 791 821 long curoff = dptr_TellDir(conn->dirptr); 792 dname = dptr_ReadDirName(c onn->dirptr, &curoff, &sbuf);822 dname = dptr_ReadDirName(ctx, conn->dirptr, &curoff, &sbuf); 793 823 794 824 DEBUG(6,("readdir on dirptr 0x%lx now at offset %ld\n", 795 825 (long)conn->dirptr,TellDir(conn->dirptr->dir_hnd))); 796 797 if (dname == NULL) 826 827 if (dname == NULL) { 798 828 return(False); 799 800 pstrcpy(filename,dname); 829 } 830 831 filename = dname; 801 832 802 833 /* notice the special *.* handling. This appears to be the only difference … … 807 838 mask_match_search(filename,mask,False) || 808 839 mangle_mask_match(conn,filename,mask)) { 809 810 if (!mangle_is_8_3(filename, False, conn->params)) 811 mangle_map(filename,True,False, 812 conn->params); 813 814 pstrcpy(fname,filename); 815 *path = 0; 816 pstrcpy(path,conn->dirpath); 817 if(needslash) 818 pstrcat(path,"/"); 819 pstrcpy(pathreal,path); 820 pstrcat(path,fname); 821 pstrcat(pathreal,dname); 840 char mname[13]; 841 842 if (!mangle_is_8_3(filename, False, conn->params)) { 843 if (!name_to_8_3(filename,mname,False, 844 conn->params)) { 845 continue; 846 } 847 filename = mname; 848 } 849 850 if (needslash) { 851 pathreal = talloc_asprintf(ctx, 852 "%s/%s", 853 conn->dirpath, 854 dname); 855 } else { 856 pathreal = talloc_asprintf(ctx, 857 "%s%s", 858 conn->dirpath, 859 dname); 860 } 861 if (!pathreal) { 862 return False; 863 } 864 822 865 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn, pathreal, &sbuf)) != 0) { 823 DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) )); 866 DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n", 867 pathreal, strerror(errno) )); 868 TALLOC_FREE(pathreal); 824 869 continue; 825 870 } 826 871 827 872 *mode = dos_mode(conn,pathreal,&sbuf); 828 873 829 874 if (!dir_check_ftype(conn,*mode,dirtype)) { 830 875 DEBUG(5,("[%s] attribs 0x%x didn't match 0x%x\n",filename,(unsigned int)*mode,(unsigned int)dirtype)); 876 TALLOC_FREE(pathreal); 831 877 continue; 832 878 } … … 835 881 *date = sbuf.st_mtime; 836 882 837 DEBUG(3,("get_dir_entry mask=[%s] found %s fname=%s\n",mask, pathreal,fname)); 883 DEBUG(3,("get_dir_entry mask=[%s] found %s " 884 "fname=%s (%s)\n", 885 mask, 886 pathreal, 887 dname, 888 filename)); 838 889 839 890 found = True; 840 891 892 *pp_fname_out = talloc_strdup(ctx, filename); 893 if (!*pp_fname_out) { 894 return False; 895 } 896 841 897 DirCacheAdd(conn->dirptr->dir_hnd, dname, curoff); 898 TALLOC_FREE(pathreal); 842 899 } 843 900 } … … 879 936 880 937 if(S_ISDIR(pst->st_mode)) { 881 status = open_directory(conn, name, pst,938 status = open_directory(conn, NULL, name, pst, 882 939 READ_CONTROL_ACCESS, 883 940 FILE_SHARE_READ|FILE_SHARE_WRITE, … … 887 944 NULL, &fsp); 888 945 } else { 889 status = open_file_stat(conn, name, pst, &fsp);946 status = open_file_stat(conn, NULL, name, pst, &fsp); 890 947 } 891 948 … … 943 1000 return True; 944 1001 } else { 945 status = open_file_ntcreate(conn, name, pst,1002 status = open_file_ntcreate(conn, NULL, name, pst, 946 1003 FILE_WRITE_ATTRIBUTES, 947 1004 FILE_SHARE_READ|FILE_SHARE_WRITE, … … 1017 1074 1018 1075 if (hide_unreadable || hide_unwriteable || hide_special) { 1019 pstring link_target;1020 1076 char *entry = NULL; 1021 1077 … … 1027 1083 if (lp_host_msdfs() && 1028 1084 lp_msdfs_root(SNUM(conn)) && 1029 is_msdfs_link(conn, entry, link_target,NULL)) {1085 is_msdfs_link(conn, entry, NULL)) { 1030 1086 SAFE_FREE(entry); 1031 1087 return True; … … 1196 1252 if (offset == START_OF_DIRECTORY_OFFSET) { 1197 1253 RewindDir(dirp, &offset); 1198 /* 1254 /* 1199 1255 * Ok we should really set the file number here 1200 1256 * to 1 to enable ".." to be returned next. Trouble
Note:
See TracChangeset
for help on using the changeset viewer.