/[rdesktop]/sourceforge.net/trunk/rdesktop/disk.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/disk.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 783 by stargo, Fri Oct 15 18:02:45 2004 UTC revision 902 by stargo, Sun May 8 17:03:04 2005 UTC
# Line 27  Line 27 
27  #include <dirent.h>             /* opendir, closedir, readdir */  #include <dirent.h>             /* opendir, closedir, readdir */
28  #include <fnmatch.h>  #include <fnmatch.h>
29  #include <errno.h>              /* errno */  #include <errno.h>              /* errno */
30    #include <stdio.h>
31    
32  #include <utime.h>  #include <utime.h>
33  #include <time.h>               /* ctime */  #include <time.h>               /* ctime */
# Line 37  Line 38 
38  #define DIRFD(a) ((a)->DIR_FD_MEMBER_NAME)  #define DIRFD(a) ((a)->DIR_FD_MEMBER_NAME)
39  #endif  #endif
40    
41  /* TODO: let autoconf figure out everything below... */  /* TODO: Fix mntent-handling for solaris
42  #if (defined(sun) && (defined(__svr4__) || defined(__SVR4)))   * #include <sys/mntent.h> */
43  #define SOLARIS  #if (defined(HAVE_MNTENT_H) && defined(HAVE_SETMNTENT))
44    #include <mntent.h>
45    #define MNTENT_PATH "/etc/mtab"
46    #define USE_SETMNTENT
47  #endif  #endif
48    
49  #if (defined(SOLARIS) || defined (__hpux) || defined(__BEOS__))  #ifdef HAVE_SYS_VFS_H
50  #include <sys/statvfs.h>        /* solaris statvfs */  #include <sys/vfs.h>
51  /* TODO: Fix mntent-handling for solaris/hpux  #endif
52   * #include <sys/mntent.h> */  
53  #undef HAVE_MNTENT_H  #ifdef HAVE_SYS_STATVFS_H
54  #define MNTENT_PATH "/etc/mnttab"  #include <sys/statvfs.h>
55  #define STATFS_FN(path, buf) (statvfs(path,buf))  #endif
 #define STATFS_T statvfs  
 #define F_NAMELEN(buf) ((buf).f_namemax)  
56    
57  #elif (defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__APPLE__))  #ifdef HAVE_SYS_STATFS_H
58    #include <sys/statfs.h>
59    #endif
60    
61    #ifdef HAVE_SYS_PARAM_H
62  #include <sys/param.h>  #include <sys/param.h>
63    #endif
64    
65    #ifdef HAVE_SYS_MOUNT_H
66  #include <sys/mount.h>  #include <sys/mount.h>
67  #define STATFS_FN(path, buf) (statfs(path,buf))  #endif
68    
69    #include "rdesktop.h"
70    
71    #ifdef STAT_STATFS3_OSF1
72    #define STATFS_FN(path, buf) (statfs(path,buf,sizeof(buf)))
73  #define STATFS_T statfs  #define STATFS_T statfs
74  #define F_NAMELEN(buf) (NAME_MAX)  #define USE_STATFS
75    #endif
76    
77  #elif (defined(__SGI_IRIX__))  #ifdef STAT_STATVFS
 #include <sys/types.h>  
 #include <sys/statvfs.h>  
78  #define STATFS_FN(path, buf) (statvfs(path,buf))  #define STATFS_FN(path, buf) (statvfs(path,buf))
79  #define STATFS_T statvfs  #define STATFS_T statvfs
80  #define F_NAMELEN(buf) ((buf).f_namemax)  #define USE_STATVFS
81    #endif
82    
83  #else  #ifdef STAT_STATVFS64
84  #include <sys/vfs.h>            /* linux statfs */  #define STATFS_FN(path, buf) (statvfs64(path,buf))
85  #include <mntent.h>  #define STATFS_T statvfs64
86  #define HAVE_MNTENT_H  #define USE_STATVFS
87  #define MNTENT_PATH "/etc/mtab"  #endif
88    
89    #if (defined(STAT_STATFS2_FS_DATA) || defined(STAT_STATFS2_BSIZE) || defined(STAT_STATFS2_FSIZE))
90  #define STATFS_FN(path, buf) (statfs(path,buf))  #define STATFS_FN(path, buf) (statfs(path,buf))
91  #define STATFS_T statfs  #define STATFS_T statfs
92    #define USE_STATFS
93    #endif
94    
95    #ifdef STAT_STATFS4
96    #define STATFS_FN(path, buf) (statfs(path,buf,sizeof(buf),0))
97    #define STATFS_T statfs
98    #define USE_STATFS
99    #endif
100    
101    #if ((defined(USE_STATFS) && defined(HAVE_STRUCT_STATFS_F_NAMEMAX)) || (defined(USE_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_NAMEMAX)))
102    #define F_NAMELEN(buf) ((buf).f_namemax)
103    #endif
104    
105    #if ((defined(USE_STATFS) && defined(HAVE_STRUCT_STATFS_F_NAMELEN)) || (defined(USE_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_NAMELEN)))
106  #define F_NAMELEN(buf) ((buf).f_namelen)  #define F_NAMELEN(buf) ((buf).f_namelen)
107  #endif  #endif
108    
109  #include "rdesktop.h"  #ifndef F_NAMELEN
110    #define F_NAMELEN(buf) (255)
111    #endif
112    
113    /* Dummy statfs fallback */
114    #ifndef STATFS_T
115    struct dummy_statfs_t
116    {
117            long f_bfree;
118            long f_bsize;
119            long f_blocks;
120            int f_namelen;
121            int f_namemax;
122    };
123    
124    int
125    dummy_statfs(struct dummy_statfs_t *buf)
126    {
127            buf->f_blocks = 262144;
128            buf->f_bfree = 131072;
129            buf->f_bsize = 512;
130            buf->f_namelen = 255;
131            buf->f_namemax = 255;
132    
133            return 0;
134    }
135    
136    #define STATFS_T dummy_statfs_t
137    #define STATFS_FN(path,buf) (dummy_statfs(buf))
138    #endif
139    
140  extern RDPDR_DEVICE g_rdpdr_device[];  extern RDPDR_DEVICE g_rdpdr_device[];
141    
142  FILEINFO g_fileinfo[MAX_OPEN_FILES];  FILEINFO g_fileinfo[MAX_OPEN_FILES];
143    BOOL g_notify_stamp = False;
144    
145  typedef struct  typedef struct
146  {  {
# Line 90  typedef struct Line 150  typedef struct
150          char type[256];          char type[256];
151  } FsInfoType;  } FsInfoType;
152    
153    static NTSTATUS NotifyInfo(NTHANDLE handle, uint32 info_class, NOTIFY * p);
154    
155  static time_t  static time_t
156  get_create_time(struct stat *st)  get_create_time(struct stat *st)
# Line 132  convert_1970_to_filetime(uint32 high, ui Line 193  convert_1970_to_filetime(uint32 high, ui
193    
194  }  }
195    
196    /* A wrapper for ftruncate which supports growing files, even if the
197       native ftruncate doesn't. This is needed on Linux FAT filesystems,
198       for example. */
199    static int
200    ftruncate_growable(int fd, off_t length)
201    {
202            int ret;
203            off_t pos;
204            static const char zero;
205    
206            /* Try the simple method first */
207            if ((ret = ftruncate(fd, length)) != -1)
208            {
209                    return ret;
210            }
211    
212            /*
213             * Some kind of error. Perhaps we were trying to grow. Retry
214             * in a safe way.
215             */
216    
217            /* Get current position */
218            if ((pos = lseek(fd, 0, SEEK_CUR)) == -1)
219            {
220                    perror("lseek");
221                    return -1;
222            }
223    
224            /* Seek to new size */
225            if (lseek(fd, length, SEEK_SET) == -1)
226            {
227                    perror("lseek");
228                    return -1;
229            }
230    
231            /* Write a zero */
232            if (write(fd, &zero, 1) == -1)
233            {
234                    perror("write");
235                    return -1;
236            }
237    
238            /* Truncate. This shouldn't fail. */
239            if (ftruncate(fd, length) == -1)
240            {
241                    perror("ftruncate");
242                    return -1;
243            }
244    
245            /* Restore position */
246            if (lseek(fd, pos, SEEK_SET) == -1)
247            {
248                    perror("lseek");
249                    return -1;
250            }
251    
252            return 0;
253    }
254    
255    /* Just like open(2), but if a open with O_EXCL fails, retry with
256       GUARDED semantics. This might be necessary because some filesystems
257       (such as NFS filesystems mounted from a unfsd server) doesn't
258       support O_EXCL. GUARDED semantics are subject to race conditions,
259       but we can live with that.
260    */
261    static int
262    open_weak_exclusive(const char *pathname, int flags, mode_t mode)
263    {
264            int ret;
265            struct stat statbuf;
266    
267            ret = open(pathname, flags, mode);
268            if (ret != -1 || !(flags & O_EXCL))
269            {
270                    /* Success, or not using O_EXCL */
271                    return ret;
272            }
273    
274            /* An error occured, and we are using O_EXCL. In case the FS
275               doesn't support O_EXCL, some kind of error will be
276               returned. Unfortunately, we don't know which one. Linux
277               2.6.8 seems to return 524, but I cannot find a documented
278               #define for this case. So, we'll return only on errors that
279               we know aren't related to O_EXCL. */
280            switch (errno)
281            {
282                    case EACCES:
283                    case EEXIST:
284                    case EINTR:
285                    case EISDIR:
286                    case ELOOP:
287                    case ENAMETOOLONG:
288                    case ENOENT:
289                    case ENOTDIR:
290                            return ret;
291            }
292    
293            /* Retry with GUARDED semantics */
294            if (stat(pathname, &statbuf) != -1)
295            {
296                    /* File exists */
297                    errno = EEXIST;
298                    return -1;
299            }
300            else
301            {
302                    return open(pathname, flags & ~O_EXCL, mode);
303            }
304    }
305    
306  /* Enumeration of devices from rdesktop.c        */  /* Enumeration of devices from rdesktop.c        */
307  /* returns numer of units found and initialized. */  /* returns numer of units found and initialized. */
# Line 144  disk_enum_devices(uint32 * id, char *opt Line 314  disk_enum_devices(uint32 * id, char *opt
314          char *pos2;          char *pos2;
315          int count = 0;          int count = 0;
316    
317          // skip the first colon          /* skip the first colon */
318          optarg++;          optarg++;
319          while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)          while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)
320          {          {
321                  pos2 = next_arg(optarg, '=');                  pos2 = next_arg(optarg, '=');
322    
323                  strncpy(g_rdpdr_device[*id].name, optarg, sizeof(g_rdpdr_device[*id].name));                  strncpy(g_rdpdr_device[*id].name, optarg, sizeof(g_rdpdr_device[*id].name) - 1);
324                  if (strlen(optarg) > 8)                  if (strlen(optarg) > (sizeof(g_rdpdr_device[*id].name) - 1))
325                          fprintf(stderr, "share name %s truncated to %s\n", optarg,                          fprintf(stderr, "share name %s truncated to %s\n", optarg,
326                                  g_rdpdr_device[*id].name);                                  g_rdpdr_device[*id].name);
327    
# Line 182  disk_create(uint32 device_id, uint32 acc Line 352  disk_create(uint32 device_id, uint32 acc
352          flags = 0;          flags = 0;
353          mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;          mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
354    
355            if (*filename && filename[strlen(filename) - 1] == '/')
         if (filename[strlen(filename) - 1] == '/')  
356                  filename[strlen(filename) - 1] = 0;                  filename[strlen(filename) - 1] = 0;
357          sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename);          sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename);
358    
# Line 191  disk_create(uint32 device_id, uint32 acc Line 360  disk_create(uint32 device_id, uint32 acc
360          {          {
361                  case CREATE_ALWAYS:                  case CREATE_ALWAYS:
362    
363                          // Delete existing file/link.                          /* Delete existing file/link. */
364                          unlink(path);                          unlink(path);
365                          flags |= O_CREAT;                          flags |= O_CREAT;
366                          break;                          break;
367    
368                  case CREATE_NEW:                  case CREATE_NEW:
369    
370                          // If the file already exists, then fail.                          /* If the file already exists, then fail. */
371                          flags |= O_CREAT | O_EXCL;                          flags |= O_CREAT | O_EXCL;
372                          break;                          break;
373    
374                  case OPEN_ALWAYS:                  case OPEN_ALWAYS:
375    
376                          // Create if not already exists.                          /* Create if not already exists. */
377                          flags |= O_CREAT;                          flags |= O_CREAT;
378                          break;                          break;
379    
380                  case OPEN_EXISTING:                  case OPEN_EXISTING:
381    
382                          // Default behaviour                          /* Default behaviour */
383                          break;                          break;
384    
385                  case TRUNCATE_EXISTING:                  case TRUNCATE_EXISTING:
386    
387                          // If the file does not exist, then fail.                          /* If the file does not exist, then fail. */
388                          flags |= O_TRUNC;                          flags |= O_TRUNC;
389                          break;                          break;
390          }          }
391    
392          //printf("Open: \"%s\"  flags: %u, accessmask: %u sharemode: %u create disp: %u\n", path, flags_and_attributes, accessmask, sharemode, create_disposition);          /*printf("Open: \"%s\"  flags: %X, accessmask: %X sharemode: %X create disp: %X\n", path, flags_and_attributes, accessmask, sharemode, create_disposition); */
393    
394          // Get information about file and set that flag ourselfs          /* Get information about file and set that flag ourselfs */
395          if ((stat(path, &filestat) == 0) && (S_ISDIR(filestat.st_mode)))          if ((stat(path, &filestat) == 0) && (S_ISDIR(filestat.st_mode)))
396          {          {
397                  if (flags_and_attributes & FILE_NON_DIRECTORY_FILE)                  if (flags_and_attributes & FILE_NON_DIRECTORY_FILE)
# Line 276  disk_create(uint32 device_id, uint32 acc Line 445  disk_create(uint32 device_id, uint32 acc
445                          flags |= O_RDONLY;                          flags |= O_RDONLY;
446                  }                  }
447    
448                  handle = open(path, flags, mode);                  handle = open_weak_exclusive(path, flags, mode);
449                  if (handle == -1)                  if (handle == -1)
450                  {                  {
451                          switch (errno)                          switch (errno)
# Line 316  disk_create(uint32 device_id, uint32 acc Line 485  disk_create(uint32 device_id, uint32 acc
485    
486          if (dirp)          if (dirp)
487                  g_fileinfo[handle].pdir = dirp;                  g_fileinfo[handle].pdir = dirp;
488            else
489                    g_fileinfo[handle].pdir = NULL;
490    
491          g_fileinfo[handle].device_id = device_id;          g_fileinfo[handle].device_id = device_id;
492          g_fileinfo[handle].flags_and_attributes = flags_and_attributes;          g_fileinfo[handle].flags_and_attributes = flags_and_attributes;
493            g_fileinfo[handle].accessmask = accessmask;
494          strncpy(g_fileinfo[handle].path, path, 255);          strncpy(g_fileinfo[handle].path, path, 255);
495            g_fileinfo[handle].delete_on_close = False;
496            g_notify_stamp = True;
497    
498          *phandle = handle;          *phandle = handle;
499          return STATUS_SUCCESS;          return STATUS_SUCCESS;
# Line 331  disk_close(NTHANDLE handle) Line 506  disk_close(NTHANDLE handle)
506    
507          pfinfo = &(g_fileinfo[handle]);          pfinfo = &(g_fileinfo[handle]);
508    
509          if (pfinfo->flags_and_attributes & FILE_DIRECTORY_FILE)          g_notify_stamp = True;
510    
511            rdpdr_abort_io(handle, 0, STATUS_CANCELLED);
512    
513            if (pfinfo->pdir)
514          {          {
515                  closedir(pfinfo->pdir);                  if (closedir(pfinfo->pdir) < 0)
516                  //FIXME: Should check exit code                  {
517                            perror("closedir");
518                            return STATUS_INVALID_HANDLE;
519                    }
520    
521                    if (pfinfo->delete_on_close)
522                            if (rmdir(pfinfo->path) < 0)
523                            {
524                                    perror(pfinfo->path);
525                                    return STATUS_ACCESS_DENIED;
526                            }
527                    pfinfo->delete_on_close = False;
528          }          }
529          else          else
530          {          {
531                  close(handle);                  if (close(handle) < 0)
532                    {
533                            perror("close");
534                            return STATUS_INVALID_HANDLE;
535                    }
536                    if (pfinfo->delete_on_close)
537                            if (unlink(pfinfo->path) < 0)
538                            {
539                                    perror(pfinfo->path);
540                                    return STATUS_ACCESS_DENIED;
541                            }
542    
543                    pfinfo->delete_on_close = False;
544          }          }
545    
546          return STATUS_SUCCESS;          return STATUS_SUCCESS;
# Line 369  disk_read(NTHANDLE handle, uint8 * data, Line 571  disk_read(NTHANDLE handle, uint8 * data,
571                  switch (errno)                  switch (errno)
572                  {                  {
573                          case EISDIR:                          case EISDIR:
574                                  return STATUS_FILE_IS_A_DIRECTORY;                                  /* Implement 24 Byte directory read ??
575                                       with STATUS_NOT_IMPLEMENTED server doesn't read again */
576                                    /* return STATUS_FILE_IS_A_DIRECTORY; */
577                                    return STATUS_NOT_IMPLEMENTED;
578                          default:                          default:
579                                  perror("read");                                  perror("read");
580                                  return STATUS_INVALID_PARAMETER;                                  return STATUS_INVALID_PARAMETER;
# Line 417  disk_query_information(NTHANDLE handle, Line 622  disk_query_information(NTHANDLE handle,
622    
623          path = g_fileinfo[handle].path;          path = g_fileinfo[handle].path;
624    
625          // Get information about file          /* Get information about file */
626          if (fstat(handle, &filestat) != 0)          if (fstat(handle, &filestat) != 0)
627          {          {
628                  perror("stat");                  perror("stat");
# Line 425  disk_query_information(NTHANDLE handle, Line 630  disk_query_information(NTHANDLE handle,
630                  return STATUS_ACCESS_DENIED;                  return STATUS_ACCESS_DENIED;
631          }          }
632    
633          // Set file attributes          /* Set file attributes */
634          file_attributes = 0;          file_attributes = 0;
635          if (S_ISDIR(filestat.st_mode))          if (S_ISDIR(filestat.st_mode))
636                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
# Line 440  disk_query_information(NTHANDLE handle, Line 645  disk_query_information(NTHANDLE handle,
645          if (!(filestat.st_mode & S_IWUSR))          if (!(filestat.st_mode & S_IWUSR))
646                  file_attributes |= FILE_ATTRIBUTE_READONLY;                  file_attributes |= FILE_ATTRIBUTE_READONLY;
647    
648          // Return requested data          /* Return requested data */
649          switch (info_class)          switch (info_class)
650          {          {
651                  case FileBasicInformation:                  case FileBasicInformation:
652                          seconds_since_1970_to_filetime(get_create_time(&filestat), &ft_high,                          seconds_since_1970_to_filetime(get_create_time(&filestat), &ft_high,
653                                                         &ft_low);                                                         &ft_low);
654                          out_uint32_le(out, ft_low);     //create_access_time                          out_uint32_le(out, ft_low);     /* create_access_time */
655                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
656    
657                          seconds_since_1970_to_filetime(filestat.st_atime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(filestat.st_atime, &ft_high, &ft_low);
658                          out_uint32_le(out, ft_low);     //last_access_time                          out_uint32_le(out, ft_low);     /* last_access_time */
659                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
660    
661                          seconds_since_1970_to_filetime(filestat.st_mtime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(filestat.st_mtime, &ft_high, &ft_low);
662                          out_uint32_le(out, ft_low);     //last_write_time                          out_uint32_le(out, ft_low);     /* last_write_time */
663                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
664    
665                          seconds_since_1970_to_filetime(filestat.st_ctime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(filestat.st_ctime, &ft_high, &ft_low);
666                          out_uint32_le(out, ft_low);     //last_change_time                          out_uint32_le(out, ft_low);     /* last_change_time */
667                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
668    
669                          out_uint32_le(out, file_attributes);                          out_uint32_le(out, file_attributes);
# Line 466  disk_query_information(NTHANDLE handle, Line 671  disk_query_information(NTHANDLE handle,
671    
672                  case FileStandardInformation:                  case FileStandardInformation:
673    
674                          out_uint32_le(out, filestat.st_size);   //Allocation size                          out_uint32_le(out, filestat.st_size);   /* Allocation size */
675                          out_uint32_le(out, 0);                          out_uint32_le(out, 0);
676                          out_uint32_le(out, filestat.st_size);   //End of file                          out_uint32_le(out, filestat.st_size);   /* End of file */
677                          out_uint32_le(out, 0);                          out_uint32_le(out, 0);
678                          out_uint32_le(out, filestat.st_nlink);  //Number of links                          out_uint32_le(out, filestat.st_nlink);  /* Number of links */
679                          out_uint8(out, 0);      //Delete pending                          out_uint8(out, 0);      /* Delete pending */
680                          out_uint8(out, S_ISDIR(filestat.st_mode) ? 1 : 0);      //Directory                          out_uint8(out, S_ISDIR(filestat.st_mode) ? 1 : 0);      /* Directory */
681                          break;                          break;
682    
683                  case FileObjectIdInformation:                  case FileObjectIdInformation:
# Line 492  disk_query_information(NTHANDLE handle, Line 697  disk_query_information(NTHANDLE handle,
697  NTSTATUS  NTSTATUS
698  disk_set_information(NTHANDLE handle, uint32 info_class, STREAM in, STREAM out)  disk_set_information(NTHANDLE handle, uint32 info_class, STREAM in, STREAM out)
699  {  {
700          uint32 device_id, length, file_attributes, ft_high, ft_low;          uint32 length, file_attributes, ft_high, ft_low, delete_on_close;
701          char newname[256], fullpath[256];          char newname[256], fullpath[256];
702          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
   
703          int mode;          int mode;
704          struct stat filestat;          struct stat filestat;
705          time_t write_time, change_time, access_time, mod_time;          time_t write_time, change_time, access_time, mod_time;
# Line 503  disk_set_information(NTHANDLE handle, ui Line 707  disk_set_information(NTHANDLE handle, ui
707          struct STATFS_T stat_fs;          struct STATFS_T stat_fs;
708    
709          pfinfo = &(g_fileinfo[handle]);          pfinfo = &(g_fileinfo[handle]);
710            g_notify_stamp = True;
711    
712          switch (info_class)          switch (info_class)
713          {          {
# Line 512  disk_set_information(NTHANDLE handle, ui Line 717  disk_set_information(NTHANDLE handle, ui
717                          in_uint8s(in, 4);       /* Handle of root dir? */                          in_uint8s(in, 4);       /* Handle of root dir? */
718                          in_uint8s(in, 24);      /* unknown */                          in_uint8s(in, 24);      /* unknown */
719    
720                          // CreationTime                          /* CreationTime */
721                          in_uint32_le(in, ft_low);                          in_uint32_le(in, ft_low);
722                          in_uint32_le(in, ft_high);                          in_uint32_le(in, ft_high);
723    
724                          // AccessTime                          /* AccessTime */
725                          in_uint32_le(in, ft_low);                          in_uint32_le(in, ft_low);
726                          in_uint32_le(in, ft_high);                          in_uint32_le(in, ft_high);
727                          if (ft_low || ft_high)                          if (ft_low || ft_high)
728                                  access_time = convert_1970_to_filetime(ft_high, ft_low);                                  access_time = convert_1970_to_filetime(ft_high, ft_low);
729    
730                          // WriteTime                          /* WriteTime */
731                          in_uint32_le(in, ft_low);                          in_uint32_le(in, ft_low);
732                          in_uint32_le(in, ft_high);                          in_uint32_le(in, ft_high);
733                          if (ft_low || ft_high)                          if (ft_low || ft_high)
734                                  write_time = convert_1970_to_filetime(ft_high, ft_low);                                  write_time = convert_1970_to_filetime(ft_high, ft_low);
735    
736                          // ChangeTime                          /* ChangeTime */
737                          in_uint32_le(in, ft_low);                          in_uint32_le(in, ft_low);
738                          in_uint32_le(in, ft_high);                          in_uint32_le(in, ft_high);
739                          if (ft_low || ft_high)                          if (ft_low || ft_high)
# Line 562  disk_set_information(NTHANDLE handle, ui Line 767  disk_set_information(NTHANDLE handle, ui
767                                  printf("FileBasicInformation modification time %s",                                  printf("FileBasicInformation modification time %s",
768                                         ctime(&tvs.modtime));                                         ctime(&tvs.modtime));
769  #endif  #endif
770                                  if (utime(pfinfo->path, &tvs))                                  if (utime(pfinfo->path, &tvs) && errno != EPERM)
771                                          return STATUS_ACCESS_DENIED;                                          return STATUS_ACCESS_DENIED;
772                          }                          }
773    
774                          if (!file_attributes)                          if (!file_attributes)
775                                  break;  // not valid                                  break;  /* not valid */
776    
777                          mode = filestat.st_mode;                          mode = filestat.st_mode;
778    
# Line 620  disk_set_information(NTHANDLE handle, ui Line 825  disk_set_information(NTHANDLE handle, ui
825                             FileDispositionInformation requests with                             FileDispositionInformation requests with
826                             DeleteFile set to FALSE should unschedule                             DeleteFile set to FALSE should unschedule
827                             the delete. See                             the delete. See
828                             http://www.osronline.com/article.cfm?article=245. Currently,                             http://www.osronline.com/article.cfm?article=245. */
                            we are deleting the file immediately. I  
                            guess this is a FIXME. */  
   
                         //in_uint32_le(in, delete_on_close);  
829    
830                          /* Make sure we close the file before                          in_uint32_le(in, delete_on_close);
                            unlinking it. Not doing so would trigger  
                            silly-delete if using NFS, which might fail  
                            on FAT floppies, for example. */  
                         disk_close(handle);  
831    
832                          if ((pfinfo->flags_and_attributes & FILE_DIRECTORY_FILE))       // remove a directory                          if (delete_on_close ||
833                                (pfinfo->
834                                 accessmask & (FILE_DELETE_ON_CLOSE | FILE_COMPLETE_IF_OPLOCKED)))
835                          {                          {
836                                  if (rmdir(pfinfo->path) < 0)                                  pfinfo->delete_on_close = True;
                                         return STATUS_ACCESS_DENIED;  
837                          }                          }
                         else if (unlink(pfinfo->path) < 0)      // unlink a file  
                                 return STATUS_ACCESS_DENIED;  
838    
839                          break;                          break;
840    
# Line 655  disk_set_information(NTHANDLE handle, ui Line 851  disk_set_information(NTHANDLE handle, ui
851    
852                          /* prevents start of writing if not enough space left on device */                          /* prevents start of writing if not enough space left on device */
853                          if (STATFS_FN(g_rdpdr_device[pfinfo->device_id].local_path, &stat_fs) == 0)                          if (STATFS_FN(g_rdpdr_device[pfinfo->device_id].local_path, &stat_fs) == 0)
854                                  if (stat_fs.f_bsize * stat_fs.f_bfree < length)                                  if (stat_fs.f_bfree * stat_fs.f_bsize < length)
855                                          return STATUS_DISK_FULL;                                          return STATUS_DISK_FULL;
856    
857                          /* FIXME: Growing file with ftruncate doesn't                          if (ftruncate_growable(handle, length) != 0)
                            work with Linux FAT fs */  
                         if (ftruncate(handle, length) != 0)  
858                          {                          {
                                 perror("ftruncate");  
859                                  return STATUS_DISK_FULL;                                  return STATUS_DISK_FULL;
860                          }                          }
861    
# Line 675  disk_set_information(NTHANDLE handle, ui Line 868  disk_set_information(NTHANDLE handle, ui
868          return STATUS_SUCCESS;          return STATUS_SUCCESS;
869  }  }
870    
871    NTSTATUS
872    disk_check_notify(NTHANDLE handle)
873    {
874            struct fileinfo *pfinfo;
875            NTSTATUS status = STATUS_PENDING;
876    
877            NOTIFY notify;
878    
879            pfinfo = &(g_fileinfo[handle]);
880            if (!pfinfo->pdir)
881                    return STATUS_INVALID_DEVICE_REQUEST;
882    
883    
884    
885            status = NotifyInfo(handle, pfinfo->info_class, &notify);
886    
887            if (status != STATUS_PENDING)
888                    return status;
889    
890            if (memcmp(&pfinfo->notify, &notify, sizeof(NOTIFY)))
891            {
892                    /*printf("disk_check_notify found changed event\n"); */
893                    memcpy(&pfinfo->notify, &notify, sizeof(NOTIFY));
894                    status = STATUS_NOTIFY_ENUM_DIR;
895            }
896    
897            return status;
898    
899    
900    }
901    
902    NTSTATUS
903    disk_create_notify(NTHANDLE handle, uint32 info_class)
904    {
905    
906            struct fileinfo *pfinfo;
907            NTSTATUS ret = STATUS_PENDING;
908    
909            /* printf("start disk_create_notify info_class %X\n", info_class); */
910    
911            pfinfo = &(g_fileinfo[handle]);
912            pfinfo->info_class = info_class;
913    
914            ret = NotifyInfo(handle, info_class, &pfinfo->notify);
915    
916            if (info_class & 0x1000)
917            {                       /* ???? */
918                    if (ret == STATUS_PENDING)
919                            return STATUS_SUCCESS;
920            }
921    
922            /* printf("disk_create_notify: num_entries %d\n", pfinfo->notify.num_entries); */
923    
924    
925            return ret;
926    
927    }
928    
929    static NTSTATUS
930    NotifyInfo(NTHANDLE handle, uint32 info_class, NOTIFY * p)
931    {
932            struct fileinfo *pfinfo;
933            struct stat buf;
934            struct dirent *dp;
935            char *fullname;
936            DIR *dpr;
937    
938            pfinfo = &(g_fileinfo[handle]);
939            if (fstat(handle, &buf) < 0)
940            {
941                    perror("NotifyInfo");
942                    return STATUS_ACCESS_DENIED;
943            }
944            p->modify_time = buf.st_mtime;
945            p->status_time = buf.st_ctime;
946            p->num_entries = 0;
947            p->total_time = 0;
948    
949    
950            dpr = opendir(pfinfo->path);
951            if (!dpr)
952            {
953                    perror("NotifyInfo");
954                    return STATUS_ACCESS_DENIED;
955            }
956    
957    
958            while ((dp = readdir(dpr)))
959            {
960                    if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
961                            continue;
962                    p->num_entries++;
963                    fullname = xmalloc(strlen(pfinfo->path) + strlen(dp->d_name) + 2);
964                    sprintf(fullname, "%s/%s", pfinfo->path, dp->d_name);
965    
966                    if (!stat(fullname, &buf))
967                    {
968                            p->total_time += (buf.st_mtime + buf.st_ctime);
969                    }
970    
971                    xfree(fullname);
972            }
973            closedir(dpr);
974    
975            return STATUS_PENDING;
976    }
977    
978  static FsInfoType *  static FsInfoType *
979  FsVolumeInfo(char *fpath)  FsVolumeInfo(char *fpath)
980  {  {
981    
982  #ifdef HAVE_MNTENT_H          static FsInfoType info;
983    #ifdef USE_SETMNTENT
984          FILE *fdfs;          FILE *fdfs;
985          struct mntent *e;          struct mntent *e;
986          static FsInfoType info;  #endif
987    
988          /* initialize */          /* initialize */
989          memset(&info, 0, sizeof(info));          memset(&info, 0, sizeof(info));
990          strcpy(info.label, "RDESKTOP");          strcpy(info.label, "RDESKTOP");
991          strcpy(info.type, "RDPFS");          strcpy(info.type, "RDPFS");
992    
993    #ifdef USE_SETMNTENT
994          fdfs = setmntent(MNTENT_PATH, "r");          fdfs = setmntent(MNTENT_PATH, "r");
995          if (!fdfs)          if (!fdfs)
996                  return &info;                  return &info;
# Line 722  FsVolumeInfo(char *fpath) Line 1024  FsVolumeInfo(char *fpath)
1024                                                  read(fd, buf, sizeof(buf));                                                  read(fd, buf, sizeof(buf));
1025                                                  strncpy(info.label, buf + 41, 32);                                                  strncpy(info.label, buf + 41, 32);
1026                                                  info.label[32] = '\0';                                                  info.label[32] = '\0';
1027                                                  //info.Serial = (buf[128]<<24)+(buf[127]<<16)+(buf[126]<<8)+buf[125];                                                  /* info.Serial = (buf[128]<<24)+(buf[127]<<16)+(buf[126]<<8)+buf[125]; */
1028                                          }                                          }
1029                                          close(fd);                                          close(fd);
1030                                  }                                  }
# Line 731  FsVolumeInfo(char *fpath) Line 1033  FsVolumeInfo(char *fpath)
1033          }          }
1034          endmntent(fdfs);          endmntent(fdfs);
1035  #else  #else
         static FsInfoType info;  
   
1036          /* initialize */          /* initialize */
1037          memset(&info, 0, sizeof(info));          memset(&info, 0, sizeof(info));
1038          strcpy(info.label, "RDESKTOP");          strcpy(info.label, "RDESKTOP");
# Line 827  disk_query_directory(NTHANDLE handle, ui Line 1127  disk_query_directory(NTHANDLE handle, ui
1127          {          {
1128                  case FileBothDirectoryInformation:                  case FileBothDirectoryInformation:
1129    
1130                          // If a search pattern is received, remember this pattern, and restart search                          /* If a search pattern is received, remember this pattern, and restart search */
1131                          if (pattern[0] != 0)                          if (pattern[0] != 0)
1132                          {                          {
1133                                  strncpy(pfinfo->pattern, 1 + strrchr(pattern, '/'), 64);                                  strncpy(pfinfo->pattern, 1 + strrchr(pattern, '/'), 64);
1134                                  rewinddir(pdir);                                  rewinddir(pdir);
1135                          }                          }
1136    
1137                          // find next dirent matching pattern                          /* find next dirent matching pattern */
1138                          pdirent = readdir(pdir);                          pdirent = readdir(pdir);
1139                          while (pdirent && fnmatch(pfinfo->pattern, pdirent->d_name, 0) != 0)                          while (pdirent && fnmatch(pfinfo->pattern, pdirent->d_name, 0) != 0)
1140                                  pdirent = readdir(pdir);                                  pdirent = readdir(pdir);
# Line 842  disk_query_directory(NTHANDLE handle, ui Line 1142  disk_query_directory(NTHANDLE handle, ui
1142                          if (pdirent == NULL)                          if (pdirent == NULL)
1143                                  return STATUS_NO_MORE_FILES;                                  return STATUS_NO_MORE_FILES;
1144    
1145                          // Get information for directory entry                          /* Get information for directory entry */
1146                          sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);                          sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);
1147    
1148                          if (stat(fullpath, &fstat))                          if (stat(fullpath, &fstat))
# Line 873  disk_query_directory(NTHANDLE handle, ui Line 1173  disk_query_directory(NTHANDLE handle, ui
1173                          if (!(fstat.st_mode & S_IWUSR))                          if (!(fstat.st_mode & S_IWUSR))
1174                                  file_attributes |= FILE_ATTRIBUTE_READONLY;                                  file_attributes |= FILE_ATTRIBUTE_READONLY;
1175    
1176                          // Return requested information                          /* Return requested information */
1177                          out_uint8s(out, 8);     //unknown zero                          out_uint8s(out, 8);     /* unknown zero */
1178    
1179                          seconds_since_1970_to_filetime(get_create_time(&fstat), &ft_high, &ft_low);                          seconds_since_1970_to_filetime(get_create_time(&fstat), &ft_high, &ft_low);
1180                          out_uint32_le(out, ft_low);     // create time                          out_uint32_le(out, ft_low);     /* create time */
1181                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
1182    
1183                          seconds_since_1970_to_filetime(fstat.st_atime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(fstat.st_atime, &ft_high, &ft_low);
1184                          out_uint32_le(out, ft_low);     //last_access_time                          out_uint32_le(out, ft_low);     /* last_access_time */
1185                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
1186    
1187                          seconds_since_1970_to_filetime(fstat.st_mtime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(fstat.st_mtime, &ft_high, &ft_low);
1188                          out_uint32_le(out, ft_low);     //last_write_time                          out_uint32_le(out, ft_low);     /* last_write_time */
1189                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
1190    
1191                          seconds_since_1970_to_filetime(fstat.st_ctime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(fstat.st_ctime, &ft_high, &ft_low);
1192                          out_uint32_le(out, ft_low);     //change_write_time                          out_uint32_le(out, ft_low);     /* change_write_time */
1193                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
1194    
1195                          out_uint32_le(out, fstat.st_size);      //filesize low                          out_uint32_le(out, fstat.st_size);      /* filesize low */
1196                          out_uint32_le(out, 0);  //filesize high                          out_uint32_le(out, 0);  /* filesize high */
1197                          out_uint32_le(out, fstat.st_size);      //filesize low                          out_uint32_le(out, fstat.st_size);      /* filesize low */
1198                          out_uint32_le(out, 0);  //filesize high                          out_uint32_le(out, 0);  /* filesize high */
1199                          out_uint32_le(out, file_attributes);                          out_uint32_le(out, file_attributes);
1200                          out_uint8(out, 2 * strlen(pdirent->d_name) + 2);        //unicode length                          out_uint8(out, 2 * strlen(pdirent->d_name) + 2);        /* unicode length */
1201                          out_uint8s(out, 7);     //pad?                          out_uint8s(out, 7);     /* pad? */
1202                          out_uint8(out, 0);      //8.3 file length                          out_uint8(out, 0);      /* 8.3 file length */
1203                          out_uint8s(out, 2 * 12);        //8.3 unicode length                          out_uint8s(out, 2 * 12);        /* 8.3 unicode length */
1204                          rdp_out_unistr(out, pdirent->d_name, 2 * strlen(pdirent->d_name));                          rdp_out_unistr(out, pdirent->d_name, 2 * strlen(pdirent->d_name));
1205                          break;                          break;
1206    
# Line 921  disk_query_directory(NTHANDLE handle, ui Line 1221  disk_query_directory(NTHANDLE handle, ui
1221  static NTSTATUS  static NTSTATUS
1222  disk_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out)  disk_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
1223  {  {
         uint32 result;  
   
1224          if (((request >> 16) != 20) || ((request >> 16) != 9))          if (((request >> 16) != 20) || ((request >> 16) != 9))
1225                  return STATUS_INVALID_PARAMETER;                  return STATUS_INVALID_PARAMETER;
1226    
# Line 934  disk_device_control(NTHANDLE handle, uin Line 1232  disk_device_control(NTHANDLE handle, uin
1232    
1233          switch (request)          switch (request)
1234          {          {
1235                  case 25:        // ?                  case 25:        /* ? */
1236                  case 42:        // ?                  case 42:        /* ? */
1237                  default:                  default:
1238                          unimpl("DISK IOCTL %d\n", request);                          unimpl("DISK IOCTL %d\n", request);
1239                          return STATUS_INVALID_PARAMETER;                          return STATUS_INVALID_PARAMETER;

Legend:
Removed from v.783  
changed lines
  Added in v.902

  ViewVC Help
Powered by ViewVC 1.1.26