modules/vfs_shadow_copy.c

説明を見る。
00001 /* 
00002  * implementation of an Shadow Copy module
00003  *
00004  * Copyright (C) Stefan Metzmacher      2003-2004
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *  
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *  
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #include "includes.h"
00022 
00023 /*
00024     Please read the VFS module Samba-HowTo-Collection.
00025     there's a chapter about this module
00026 
00027     For this share
00028     Z:\
00029 
00030     the ShadowCopies are in this directories
00031 
00032     Z:\@GMT-2003.08.05-12.00.00\
00033     Z:\@GMT-2003.08.05-12.01.00\
00034     Z:\@GMT-2003.08.05-12.02.00\
00035 
00036     e.g.
00037     
00038     Z:\testfile.txt
00039     Z:\@GMT-2003.08.05-12.02.00\testfile.txt
00040 
00041     or:
00042 
00043     Z:\testdir\testfile.txt
00044     Z:\@GMT-2003.08.05-12.02.00\testdir\testfile.txt
00045 
00046 
00047     Note: Files must differ to be displayed via Windows Explorer!
00048           Directories are always displayed...    
00049 */
00050 
00051 static int vfs_shadow_copy_debug_level = DBGC_VFS;
00052 
00053 #undef DBGC_CLASS
00054 #define DBGC_CLASS vfs_shadow_copy_debug_level
00055 
00056 #define SHADOW_COPY_PREFIX "@GMT-"
00057 #define SHADOW_COPY_SAMPLE "@GMT-2004.02.18-15.44.00"
00058 
00059 typedef struct {
00060         int pos;
00061         int num;
00062         SMB_STRUCT_DIRENT *dirs;
00063 } shadow_copy_Dir;
00064 
00065 static BOOL shadow_copy_match_name(const char *name)
00066 {
00067         if (strncmp(SHADOW_COPY_PREFIX,name, sizeof(SHADOW_COPY_PREFIX)-1)==0 &&
00068                 (strlen(SHADOW_COPY_SAMPLE) == strlen(name))) {
00069                 return True;
00070         }
00071 
00072         return False;
00073 }
00074 
00075 static SMB_STRUCT_DIR *shadow_copy_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
00076 {
00077         shadow_copy_Dir *dirp;
00078         SMB_STRUCT_DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fname,mask,attr);
00079 
00080         if (!p) {
00081                 DEBUG(0,("shadow_copy_opendir: SMB_VFS_NEXT_OPENDIR() failed for [%s]\n",fname));
00082                 return NULL;
00083         }
00084 
00085         dirp = SMB_MALLOC_P(shadow_copy_Dir);
00086         if (!dirp) {
00087                 DEBUG(0,("shadow_copy_opendir: Out of memory\n"));
00088                 SMB_VFS_NEXT_CLOSEDIR(handle,p);
00089                 return NULL;
00090         }
00091 
00092         ZERO_STRUCTP(dirp);
00093 
00094         while (True) {
00095                 SMB_STRUCT_DIRENT *d;
00096 
00097                 d = SMB_VFS_NEXT_READDIR(handle, p);
00098                 if (d == NULL) {
00099                         break;
00100                 }
00101 
00102                 if (shadow_copy_match_name(d->d_name)) {
00103                         DEBUG(8,("shadow_copy_opendir: hide [%s]\n",d->d_name));
00104                         continue;
00105                 }
00106 
00107                 DEBUG(10,("shadow_copy_opendir: not hide [%s]\n",d->d_name));
00108 
00109                 dirp->dirs = SMB_REALLOC_ARRAY(dirp->dirs,SMB_STRUCT_DIRENT, dirp->num+1);
00110                 if (!dirp->dirs) {
00111                         DEBUG(0,("shadow_copy_opendir: Out of memory\n"));
00112                         break;
00113                 }
00114 
00115                 dirp->dirs[dirp->num++] = *d;
00116         }
00117 
00118         SMB_VFS_NEXT_CLOSEDIR(handle,p);
00119         return((SMB_STRUCT_DIR *)dirp);
00120 }
00121 
00122 static SMB_STRUCT_DIRENT *shadow_copy_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp)
00123 {
00124         shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
00125 
00126         if (dirp->pos < dirp->num) {
00127                 return &(dirp->dirs[dirp->pos++]);
00128         }
00129 
00130         return NULL;
00131 }
00132 
00133 static void shadow_copy_seekdir(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp, long offset)
00134 {
00135         shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
00136 
00137         if (offset < dirp->num) {
00138                 dirp->pos = offset ;
00139         }
00140 }
00141 
00142 static long shadow_copy_telldir(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp)
00143 {
00144         shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
00145         return( dirp->pos ) ;
00146 }
00147 
00148 static void shadow_copy_rewinddir(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp)
00149 {
00150         shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
00151         dirp->pos = 0 ;
00152 }
00153 
00154 static int shadow_copy_closedir(vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp)
00155 {
00156         shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
00157 
00158         SAFE_FREE(dirp->dirs);
00159         SAFE_FREE(dirp);
00160  
00161         return 0;       
00162 }
00163 
00164 static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels)
00165 {
00166         SMB_STRUCT_DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fsp->conn->connectpath,NULL,0);
00167 
00168         shadow_copy_data->num_volumes = 0;
00169         shadow_copy_data->labels = NULL;
00170 
00171         if (!p) {
00172                 DEBUG(0,("shadow_copy_get_shadow_copy_data: SMB_VFS_NEXT_OPENDIR() failed for [%s]\n",fsp->conn->connectpath));
00173                 return -1;
00174         }
00175 
00176         while (True) {
00177                 SHADOW_COPY_LABEL *tlabels;
00178                 SMB_STRUCT_DIRENT *d;
00179 
00180                 d = SMB_VFS_NEXT_READDIR(handle, p);
00181                 if (d == NULL) {
00182                         break;
00183                 }
00184 
00185                 /* */
00186                 if (!shadow_copy_match_name(d->d_name)) {
00187                         DEBUG(10,("shadow_copy_get_shadow_copy_data: ignore [%s]\n",d->d_name));
00188                         continue;
00189                 }
00190 
00191                 DEBUG(7,("shadow_copy_get_shadow_copy_data: not ignore [%s]\n",d->d_name));
00192 
00193                 if (!labels) {
00194                         shadow_copy_data->num_volumes++;
00195                         continue;
00196                 }
00197 
00198                 tlabels = (SHADOW_COPY_LABEL *)TALLOC_REALLOC(shadow_copy_data->mem_ctx,
00199                                                                         shadow_copy_data->labels,
00200                                                                         (shadow_copy_data->num_volumes+1)*sizeof(SHADOW_COPY_LABEL));
00201                 if (tlabels == NULL) {
00202                         DEBUG(0,("shadow_copy_get_shadow_copy_data: Out of memory\n"));
00203                         SMB_VFS_NEXT_CLOSEDIR(handle,p);
00204                         return -1;
00205                 }
00206 
00207                 snprintf(tlabels[shadow_copy_data->num_volumes++], sizeof(*tlabels), "%s",d->d_name);
00208 
00209                 shadow_copy_data->labels = tlabels;
00210         }
00211 
00212         SMB_VFS_NEXT_CLOSEDIR(handle,p);
00213         return 0;
00214 }
00215 
00216 /* VFS operations structure */
00217 
00218 static vfs_op_tuple shadow_copy_ops[] = {
00219         {SMB_VFS_OP(shadow_copy_opendir),               SMB_VFS_OP_OPENDIR,             SMB_VFS_LAYER_TRANSPARENT},
00220         {SMB_VFS_OP(shadow_copy_readdir),               SMB_VFS_OP_READDIR,             SMB_VFS_LAYER_TRANSPARENT},
00221         {SMB_VFS_OP(shadow_copy_seekdir),               SMB_VFS_OP_SEEKDIR,             SMB_VFS_LAYER_TRANSPARENT},
00222         {SMB_VFS_OP(shadow_copy_telldir),               SMB_VFS_OP_TELLDIR,             SMB_VFS_LAYER_TRANSPARENT},
00223         {SMB_VFS_OP(shadow_copy_rewinddir),             SMB_VFS_OP_REWINDDIR,           SMB_VFS_LAYER_TRANSPARENT},
00224         {SMB_VFS_OP(shadow_copy_closedir),              SMB_VFS_OP_CLOSEDIR,            SMB_VFS_LAYER_TRANSPARENT},
00225 
00226         {SMB_VFS_OP(shadow_copy_get_shadow_copy_data),  SMB_VFS_OP_GET_SHADOW_COPY_DATA,SMB_VFS_LAYER_OPAQUE},
00227 
00228         {SMB_VFS_OP(NULL),                              SMB_VFS_OP_NOOP,                SMB_VFS_LAYER_NOOP}
00229 };
00230 
00231 NTSTATUS vfs_shadow_copy_init(void);
00232 NTSTATUS vfs_shadow_copy_init(void)
00233 {
00234         NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "shadow_copy", shadow_copy_ops);
00235 
00236         if (!NT_STATUS_IS_OK(ret))
00237                 return ret;
00238 
00239         vfs_shadow_copy_debug_level = debug_add_class("shadow_copy");
00240         if (vfs_shadow_copy_debug_level == -1) {
00241                 vfs_shadow_copy_debug_level = DBGC_VFS;
00242                 DEBUG(0, ("%s: Couldn't register custom debugging class!\n",
00243                         "vfs_shadow_copy_init"));
00244         } else {
00245                 DEBUG(10, ("%s: Debug class number of '%s': %d\n", 
00246                         "vfs_shadow_copy_init","shadow_copy",vfs_shadow_copy_debug_level));
00247         }
00248 
00249         return ret;
00250 }

Sambaに対してSat Aug 29 21:23:07 2009に生成されました。  doxygen 1.4.7