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

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

  ViewVC Help
Powered by ViewVC 1.1.26