/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/disk.c

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

revision 747 by astrand, Mon Aug 9 13:50:41 2004 UTC revision 865 by stargo, Tue Mar 15 11:25:50 2005 UTC
# Line 18  Line 18 
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21    #include "rdesktop.h"
22  #include "disk.h"  #include "disk.h"
23    
24  #include <sys/types.h>  #include <sys/types.h>
# Line 31  Line 32 
32  #include <utime.h>  #include <utime.h>
33  #include <time.h>               /* ctime */  #include <time.h>               /* ctime */
34    
35  #if defined(HAVE_DIRFD)  #if (defined(HAVE_DIRFD) || (HAVE_DECL_DIRFD == 1))
36  #define DIRFD(a) (dirfd(a))  #define DIRFD(a) (dirfd(a))
37  #else  #else
38  #define DIRFD(a) ((a)->DIR_FD_MEMBER_NAME)  #define DIRFD(a) ((a)->DIR_FD_MEMBER_NAME)
# Line 52  Line 53 
53  #define STATFS_T statvfs  #define STATFS_T statvfs
54  #define F_NAMELEN(buf) ((buf).f_namemax)  #define F_NAMELEN(buf) ((buf).f_namemax)
55    
56  #elif (defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__))  #elif (defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__APPLE__))
57  #include <sys/param.h>  #include <sys/param.h>
58  #include <sys/mount.h>  #include <sys/mount.h>
59  #define STATFS_FN(path, buf) (statfs(path,buf))  #define STATFS_FN(path, buf) (statfs(path,buf))
# Line 66  Line 67 
67  #define STATFS_T statvfs  #define STATFS_T statvfs
68  #define F_NAMELEN(buf) ((buf).f_namemax)  #define F_NAMELEN(buf) ((buf).f_namemax)
69    
70    #elif (defined(__alpha) && !defined(linux))
71    #include <sys/mount.h>          /* osf1 statfs */
72    #define STATFS_FN(path, buf) (statfs(path,buf,sizeof(buf)))
73    #define STATFS_T statfs
74    #define F_NAMELEN(buf) (255)
75    
76  #else  #else
77  #include <sys/vfs.h>            /* linux statfs */  #include <sys/vfs.h>            /* linux statfs */
78  #include <mntent.h>  #include <mntent.h>
# Line 76  Line 83 
83  #define F_NAMELEN(buf) ((buf).f_namelen)  #define F_NAMELEN(buf) ((buf).f_namelen)
84  #endif  #endif
85    
 #include "rdesktop.h"  
   
86  extern RDPDR_DEVICE g_rdpdr_device[];  extern RDPDR_DEVICE g_rdpdr_device[];
87    
88  FILEINFO g_fileinfo[MAX_OPEN_FILES];  FILEINFO g_fileinfo[MAX_OPEN_FILES];
89    BOOL g_notify_stamp = False;
90    
91  typedef struct  typedef struct
92  {  {
# Line 90  typedef struct Line 96  typedef struct
96          char type[256];          char type[256];
97  } FsInfoType;  } FsInfoType;
98    
99    static NTSTATUS NotifyInfo(NTHANDLE handle, uint32 info_class, NOTIFY * p);
100    
101  static time_t  static time_t
102  get_create_time(struct stat *st)  get_create_time(struct stat *st)
# Line 132  convert_1970_to_filetime(uint32 high, ui Line 139  convert_1970_to_filetime(uint32 high, ui
139    
140  }  }
141    
142    /* A wrapper for ftruncate which supports growing files, even if the
143       native ftruncate doesn't. This is needed on Linux FAT filesystems,
144       for example. */
145    static int
146    ftruncate_growable(int fd, off_t length)
147    {
148            int ret;
149            off_t pos;
150            static const char zero;
151    
152            /* Try the simple method first */
153            if ((ret = ftruncate(fd, length)) != -1)
154            {
155                    return ret;
156            }
157    
158            /*
159             * Some kind of error. Perhaps we were trying to grow. Retry
160             * in a safe way.
161             */
162    
163            /* Get current position */
164            if ((pos = lseek(fd, 0, SEEK_CUR)) == -1)
165            {
166                    perror("lseek");
167                    return -1;
168            }
169    
170            /* Seek to new size */
171            if (lseek(fd, length, SEEK_SET) == -1)
172            {
173                    perror("lseek");
174                    return -1;
175            }
176    
177            /* Write a zero */
178            if (write(fd, &zero, 1) == -1)
179            {
180                    perror("write");
181                    return -1;
182            }
183    
184            /* Truncate. This shouldn't fail. */
185            if (ftruncate(fd, length) == -1)
186            {
187                    perror("ftruncate");
188                    return -1;
189            }
190    
191            /* Restore position */
192            if (lseek(fd, pos, SEEK_SET) == -1)
193            {
194                    perror("lseek");
195                    return -1;
196            }
197    
198            return 0;
199    }
200    
201    /* Just like open(2), but if a open with O_EXCL fails, retry with
202       GUARDED semantics. This might be necessary because some filesystems
203       (such as NFS filesystems mounted from a unfsd server) doesn't
204       support O_EXCL. GUARDED semantics are subject to race conditions,
205       but we can live with that.
206    */
207    static int
208    open_weak_exclusive(const char *pathname, int flags, mode_t mode)
209    {
210            int ret;
211            struct stat statbuf;
212    
213            ret = open(pathname, flags, mode);
214            if (ret != -1 || !(flags & O_EXCL))
215            {
216                    /* Success, or not using O_EXCL */
217                    return ret;
218            }
219    
220            /* An error occured, and we are using O_EXCL. In case the FS
221               doesn't support O_EXCL, some kind of error will be
222               returned. Unfortunately, we don't know which one. Linux
223               2.6.8 seems to return 524, but I cannot find a documented
224               #define for this case. So, we'll return only on errors that
225               we know aren't related to O_EXCL. */
226            switch (errno)
227            {
228                    case EACCES:
229                    case EEXIST:
230                    case EINTR:
231                    case EISDIR:
232                    case ELOOP:
233                    case ENAMETOOLONG:
234                    case ENOENT:
235                    case ENOTDIR:
236                            return ret;
237            }
238    
239            /* Retry with GUARDED semantics */
240            if (stat(pathname, &statbuf) != -1)
241            {
242                    /* File exists */
243                    errno = EEXIST;
244                    return -1;
245            }
246            else
247            {
248                    return open(pathname, flags & ~O_EXCL, mode);
249            }
250    }
251    
252  /* Enumeration of devices from rdesktop.c        */  /* Enumeration of devices from rdesktop.c        */
253  /* returns numer of units found and initialized. */  /* returns numer of units found and initialized. */
# Line 144  disk_enum_devices(uint32 * id, char *opt Line 260  disk_enum_devices(uint32 * id, char *opt
260          char *pos2;          char *pos2;
261          int count = 0;          int count = 0;
262    
263          // skip the first colon          /* skip the first colon */
264          optarg++;          optarg++;
265          while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)          while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)
266          {          {
267                  pos2 = next_arg(optarg, '=');                  pos2 = next_arg(optarg, '=');
268    
269                  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);
270                  if (strlen(optarg) > 8)                  if (strlen(optarg) > (sizeof(g_rdpdr_device[*id].name) - 1))
271                          fprintf(stderr, "share name %s truncated to %s\n", optarg,                          fprintf(stderr, "share name %s truncated to %s\n", optarg,
272                                  g_rdpdr_device[*id].name);                                  g_rdpdr_device[*id].name);
273    
# Line 169  disk_enum_devices(uint32 * id, char *opt Line 285  disk_enum_devices(uint32 * id, char *opt
285  /* Opens or creates a file or directory */  /* Opens or creates a file or directory */
286  static NTSTATUS  static NTSTATUS
287  disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition,  disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition,
288              uint32 flags_and_attributes, char *filename, HANDLE * phandle)              uint32 flags_and_attributes, char *filename, NTHANDLE * phandle)
289  {  {
290          HANDLE handle;          NTHANDLE handle;
291          DIR *dirp;          DIR *dirp;
292          int flags, mode;          int flags, mode;
293          char path[256];          char path[256];
# Line 182  disk_create(uint32 device_id, uint32 acc Line 298  disk_create(uint32 device_id, uint32 acc
298          flags = 0;          flags = 0;
299          mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;          mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
300    
301            if (*filename && filename[strlen(filename) - 1] == '/')
         if (filename[strlen(filename) - 1] == '/')  
302                  filename[strlen(filename) - 1] = 0;                  filename[strlen(filename) - 1] = 0;
303          sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename);          sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename);
304    
# Line 191  disk_create(uint32 device_id, uint32 acc Line 306  disk_create(uint32 device_id, uint32 acc
306          {          {
307                  case CREATE_ALWAYS:                  case CREATE_ALWAYS:
308    
309                          // Delete existing file/link.                          /* Delete existing file/link. */
310                          unlink(path);                          unlink(path);
311                          flags |= O_CREAT;                          flags |= O_CREAT;
312                          break;                          break;
313    
314                  case CREATE_NEW:                  case CREATE_NEW:
315    
316                          // If the file already exists, then fail.                          /* If the file already exists, then fail. */
317                          flags |= O_CREAT | O_EXCL;                          flags |= O_CREAT | O_EXCL;
318                          break;                          break;
319    
320                  case OPEN_ALWAYS:                  case OPEN_ALWAYS:
321    
322                          // Create if not already exists.                          /* Create if not already exists. */
323                          flags |= O_CREAT;                          flags |= O_CREAT;
324                          break;                          break;
325    
326                  case OPEN_EXISTING:                  case OPEN_EXISTING:
327    
328                          // Default behaviour                          /* Default behaviour */
329                          break;                          break;
330    
331                  case TRUNCATE_EXISTING:                  case TRUNCATE_EXISTING:
332    
333                          // If the file does not exist, then fail.                          /* If the file does not exist, then fail. */
334                          flags |= O_TRUNC;                          flags |= O_TRUNC;
335                          break;                          break;
336          }          }
337    
338          //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);*/
339    
340          // Get information about file and set that flag ourselfs          /* Get information about file and set that flag ourselfs */
341          if ((stat(path, &filestat) == 0) && (S_ISDIR(filestat.st_mode)))          if ((stat(path, &filestat) == 0) && (S_ISDIR(filestat.st_mode)))
342          {          {
343                  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 391  disk_create(uint32 device_id, uint32 acc
391                          flags |= O_RDONLY;                          flags |= O_RDONLY;
392                  }                  }
393    
394                  handle = open(path, flags, mode);                  handle = open_weak_exclusive(path, flags, mode);
395                  if (handle == -1)                  if (handle == -1)
396                  {                  {
397                          switch (errno)                          switch (errno)
# Line 316  disk_create(uint32 device_id, uint32 acc Line 431  disk_create(uint32 device_id, uint32 acc
431    
432          if (dirp)          if (dirp)
433                  g_fileinfo[handle].pdir = dirp;                  g_fileinfo[handle].pdir = dirp;
434            else
435                    g_fileinfo[handle].pdir = NULL;
436    
437          g_fileinfo[handle].device_id = device_id;          g_fileinfo[handle].device_id = device_id;
438          g_fileinfo[handle].flags_and_attributes = flags_and_attributes;          g_fileinfo[handle].flags_and_attributes = flags_and_attributes;
439            g_fileinfo[handle].accessmask = accessmask;
440          strncpy(g_fileinfo[handle].path, path, 255);          strncpy(g_fileinfo[handle].path, path, 255);
441            g_fileinfo[handle].delete_on_close = False;
442            g_notify_stamp = True;
443    
444          *phandle = handle;          *phandle = handle;
445          return STATUS_SUCCESS;          return STATUS_SUCCESS;
446  }  }
447    
448  static NTSTATUS  static NTSTATUS
449  disk_close(HANDLE handle)  disk_close(NTHANDLE handle)
450  {  {
451          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
452    
453          pfinfo = &(g_fileinfo[handle]);          pfinfo = &(g_fileinfo[handle]);
454    
455          if (pfinfo->flags_and_attributes & FILE_DIRECTORY_FILE)          g_notify_stamp = True;
456    
457            rdpdr_abort_io(handle, 0, STATUS_CANCELLED);
458    
459            if (pfinfo->pdir)
460          {          {
461                  closedir(pfinfo->pdir);                  if (closedir(pfinfo->pdir) < 0)
462                  //FIXME: Should check exit code                  {
463                            perror("closedir");
464                            return STATUS_INVALID_HANDLE;
465                    }
466    
467                    if (pfinfo->delete_on_close)
468                            if (rmdir(pfinfo->path) < 0)
469                            {
470                                    perror(pfinfo->path);
471                                    return STATUS_ACCESS_DENIED;
472                            }
473                    pfinfo->delete_on_close = False;
474          }          }
475          else          else
476          {          {
477                  close(handle);                  if (close(handle) < 0)
478                    {
479                            perror("close");
480                            return STATUS_INVALID_HANDLE;
481                    }
482                    if (pfinfo->delete_on_close)
483                            if (unlink(pfinfo->path) < 0)
484                            {
485                                    perror(pfinfo->path);
486                                    return STATUS_ACCESS_DENIED;
487                            }
488    
489                    pfinfo->delete_on_close = False;
490          }          }
491    
492          return STATUS_SUCCESS;          return STATUS_SUCCESS;
493  }  }
494    
495  static NTSTATUS  static NTSTATUS
496  disk_read(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  disk_read(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
497  {  {
498          int n;          int n;
499    
# Line 369  disk_read(HANDLE handle, uint8 * data, u Line 517  disk_read(HANDLE handle, uint8 * data, u
517                  switch (errno)                  switch (errno)
518                  {                  {
519                          case EISDIR:                          case EISDIR:
520                                  return STATUS_FILE_IS_A_DIRECTORY;                                  /* Implement 24 Byte directory read ??
521                                       with STATUS_NOT_IMPLEMENTED server doesn't read again */
522                                    /* return STATUS_FILE_IS_A_DIRECTORY; */
523                                    return STATUS_NOT_IMPLEMENTED;
524                          default:                          default:
525                                  perror("read");                                  perror("read");
526                                  return STATUS_INVALID_PARAMETER;                                  return STATUS_INVALID_PARAMETER;
# Line 382  disk_read(HANDLE handle, uint8 * data, u Line 533  disk_read(HANDLE handle, uint8 * data, u
533  }  }
534    
535  static NTSTATUS  static NTSTATUS
536  disk_write(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  disk_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
537  {  {
538          int n;          int n;
539    
# Line 409  disk_write(HANDLE handle, uint8 * data, Line 560  disk_write(HANDLE handle, uint8 * data,
560  }  }
561    
562  NTSTATUS  NTSTATUS
563  disk_query_information(HANDLE handle, uint32 info_class, STREAM out)  disk_query_information(NTHANDLE handle, uint32 info_class, STREAM out)
564  {  {
565          uint32 file_attributes, ft_high, ft_low;          uint32 file_attributes, ft_high, ft_low;
566          struct stat filestat;          struct stat filestat;
# Line 417  disk_query_information(HANDLE handle, ui Line 568  disk_query_information(HANDLE handle, ui
568    
569          path = g_fileinfo[handle].path;          path = g_fileinfo[handle].path;
570    
571          // Get information about file          /* Get information about file */
572          if (fstat(handle, &filestat) != 0)          if (fstat(handle, &filestat) != 0)
573          {          {
574                  perror("stat");                  perror("stat");
# Line 425  disk_query_information(HANDLE handle, ui Line 576  disk_query_information(HANDLE handle, ui
576                  return STATUS_ACCESS_DENIED;                  return STATUS_ACCESS_DENIED;
577          }          }
578    
579          // Set file attributes          /* Set file attributes */
580          file_attributes = 0;          file_attributes = 0;
581          if (S_ISDIR(filestat.st_mode))          if (S_ISDIR(filestat.st_mode))
582                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
# Line 440  disk_query_information(HANDLE handle, ui Line 591  disk_query_information(HANDLE handle, ui
591          if (!(filestat.st_mode & S_IWUSR))          if (!(filestat.st_mode & S_IWUSR))
592                  file_attributes |= FILE_ATTRIBUTE_READONLY;                  file_attributes |= FILE_ATTRIBUTE_READONLY;
593    
594          // Return requested data          /* Return requested data */
595          switch (info_class)          switch (info_class)
596          {          {
597                  case FileBasicInformation:                  case FileBasicInformation:
598                          seconds_since_1970_to_filetime(get_create_time(&filestat), &ft_high,                          seconds_since_1970_to_filetime(get_create_time(&filestat), &ft_high,
599                                                         &ft_low);                                                         &ft_low);
600                          out_uint32_le(out, ft_low);     //create_access_time                          out_uint32_le(out, ft_low);     /* create_access_time */
601                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
602    
603                          seconds_since_1970_to_filetime(filestat.st_atime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(filestat.st_atime, &ft_high, &ft_low);
604                          out_uint32_le(out, ft_low);     //last_access_time                          out_uint32_le(out, ft_low);     /* last_access_time */
605                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
606    
607                          seconds_since_1970_to_filetime(filestat.st_mtime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(filestat.st_mtime, &ft_high, &ft_low);
608                          out_uint32_le(out, ft_low);     //last_write_time                          out_uint32_le(out, ft_low);     /* last_write_time */
609                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
610    
611                          seconds_since_1970_to_filetime(filestat.st_ctime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(filestat.st_ctime, &ft_high, &ft_low);
612                          out_uint32_le(out, ft_low);     //last_change_time                          out_uint32_le(out, ft_low);     /* last_change_time */
613                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
614    
615                          out_uint32_le(out, file_attributes);                          out_uint32_le(out, file_attributes);
# Line 466  disk_query_information(HANDLE handle, ui Line 617  disk_query_information(HANDLE handle, ui
617    
618                  case FileStandardInformation:                  case FileStandardInformation:
619    
620                          out_uint32_le(out, filestat.st_size);   //Allocation size                          out_uint32_le(out, filestat.st_size);   /* Allocation size */
621                          out_uint32_le(out, 0);                          out_uint32_le(out, 0);
622                          out_uint32_le(out, filestat.st_size);   //End of file                          out_uint32_le(out, filestat.st_size);   /* End of file */
623                          out_uint32_le(out, 0);                          out_uint32_le(out, 0);
624                          out_uint32_le(out, filestat.st_nlink);  //Number of links                          out_uint32_le(out, filestat.st_nlink);  /* Number of links */
625                          out_uint8(out, 0);      //Delete pending                          out_uint8(out, 0);      /* Delete pending */
626                          out_uint8(out, S_ISDIR(filestat.st_mode) ? 1 : 0);      //Directory                          out_uint8(out, S_ISDIR(filestat.st_mode) ? 1 : 0);      /* Directory */
627                          break;                          break;
628    
629                  case FileObjectIdInformation:                  case FileObjectIdInformation:
# Line 490  disk_query_information(HANDLE handle, ui Line 641  disk_query_information(HANDLE handle, ui
641  }  }
642    
643  NTSTATUS  NTSTATUS
644  disk_set_information(HANDLE handle, uint32 info_class, STREAM in, STREAM out)  disk_set_information(NTHANDLE handle, uint32 info_class, STREAM in, STREAM out)
645  {  {
646          uint32 device_id, length, file_attributes, ft_high, ft_low;          uint32 length, file_attributes, ft_high, ft_low, delete_on_close;
647          char newname[256], fullpath[256];          char newname[256], fullpath[256];
648          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
   
649          int mode;          int mode;
650          struct stat filestat;          struct stat filestat;
651          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(HANDLE handle, uint Line 653  disk_set_information(HANDLE handle, uint
653          struct STATFS_T stat_fs;          struct STATFS_T stat_fs;
654    
655          pfinfo = &(g_fileinfo[handle]);          pfinfo = &(g_fileinfo[handle]);
656            g_notify_stamp = True;
657    
658          switch (info_class)          switch (info_class)
659          {          {
# Line 512  disk_set_information(HANDLE handle, uint Line 663  disk_set_information(HANDLE handle, uint
663                          in_uint8s(in, 4);       /* Handle of root dir? */                          in_uint8s(in, 4);       /* Handle of root dir? */
664                          in_uint8s(in, 24);      /* unknown */                          in_uint8s(in, 24);      /* unknown */
665    
666                          // CreationTime                          /* CreationTime */
667                          in_uint32_le(in, ft_low);                          in_uint32_le(in, ft_low);
668                          in_uint32_le(in, ft_high);                          in_uint32_le(in, ft_high);
669    
670                          // AccessTime                          /* AccessTime */
671                          in_uint32_le(in, ft_low);                          in_uint32_le(in, ft_low);
672                          in_uint32_le(in, ft_high);                          in_uint32_le(in, ft_high);
673                          if (ft_low || ft_high)                          if (ft_low || ft_high)
674                                  access_time = convert_1970_to_filetime(ft_high, ft_low);                                  access_time = convert_1970_to_filetime(ft_high, ft_low);
675    
676                          // WriteTime                          /* WriteTime */
677                          in_uint32_le(in, ft_low);                          in_uint32_le(in, ft_low);
678                          in_uint32_le(in, ft_high);                          in_uint32_le(in, ft_high);
679                          if (ft_low || ft_high)                          if (ft_low || ft_high)
680                                  write_time = convert_1970_to_filetime(ft_high, ft_low);                                  write_time = convert_1970_to_filetime(ft_high, ft_low);
681    
682                          // ChangeTime                          /* ChangeTime */
683                          in_uint32_le(in, ft_low);                          in_uint32_le(in, ft_low);
684                          in_uint32_le(in, ft_high);                          in_uint32_le(in, ft_high);
685                          if (ft_low || ft_high)                          if (ft_low || ft_high)
# Line 562  disk_set_information(HANDLE handle, uint Line 713  disk_set_information(HANDLE handle, uint
713                                  printf("FileBasicInformation modification time %s",                                  printf("FileBasicInformation modification time %s",
714                                         ctime(&tvs.modtime));                                         ctime(&tvs.modtime));
715  #endif  #endif
716                                  if (utime(pfinfo->path, &tvs))                                  if (utime(pfinfo->path, &tvs) && errno != EPERM)
717                                          return STATUS_ACCESS_DENIED;                                          return STATUS_ACCESS_DENIED;
718                          }                          }
719    
720                          if (!file_attributes)                          if (!file_attributes)
721                                  break;  // not valid                                  break;  /* not valid */
722    
723                          mode = filestat.st_mode;                          mode = filestat.st_mode;
724    
# Line 620  disk_set_information(HANDLE handle, uint Line 771  disk_set_information(HANDLE handle, uint
771                             FileDispositionInformation requests with                             FileDispositionInformation requests with
772                             DeleteFile set to FALSE should unschedule                             DeleteFile set to FALSE should unschedule
773                             the delete. See                             the delete. See
774                             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. */  
775    
776                          //in_uint32_le(in, delete_on_close);                          in_uint32_le(in, delete_on_close);
777    
778                          /* Make sure we close the file before                          if (delete_on_close ||
779                             unlinking it. Not doing so would trigger                              (pfinfo->
780                             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  
781                          {                          {
782                                  if (rmdir(pfinfo->path) < 0)                                  pfinfo->delete_on_close = True;
                                         return STATUS_ACCESS_DENIED;  
783                          }                          }
                         else if (unlink(pfinfo->path) < 0)      // unlink a file  
                                 return STATUS_ACCESS_DENIED;  
784    
785                          break;                          break;
786    
# Line 655  disk_set_information(HANDLE handle, uint Line 797  disk_set_information(HANDLE handle, uint
797    
798                          /* prevents start of writing if not enough space left on device */                          /* prevents start of writing if not enough space left on device */
799                          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)
800                                  if (stat_fs.f_bsize * stat_fs.f_bfree < length)                                  if (stat_fs.f_bfree * stat_fs.f_bsize < length)
801                                          return STATUS_DISK_FULL;                                          return STATUS_DISK_FULL;
802    
803                          /* FIXME: Growing file with ftruncate doesn't                          if (ftruncate_growable(handle, length) != 0)
                            work with Linux FAT fs */  
                         if (ftruncate(handle, length) != 0)  
804                          {                          {
                                 perror("ftruncate");  
805                                  return STATUS_DISK_FULL;                                  return STATUS_DISK_FULL;
806                          }                          }
807    
# Line 675  disk_set_information(HANDLE handle, uint Line 814  disk_set_information(HANDLE handle, uint
814          return STATUS_SUCCESS;          return STATUS_SUCCESS;
815  }  }
816    
817    NTSTATUS
818    disk_check_notify(NTHANDLE handle)
819    {
820            struct fileinfo *pfinfo;
821            NTSTATUS status = STATUS_PENDING;
822    
823            NOTIFY notify;
824    
825            pfinfo = &(g_fileinfo[handle]);
826            if (!pfinfo->pdir)
827                    return STATUS_INVALID_DEVICE_REQUEST;
828    
829    
830    
831            status = NotifyInfo(handle, pfinfo->info_class, &notify);
832    
833            if (status != STATUS_PENDING)
834                    return status;
835    
836            if (memcmp(&pfinfo->notify, &notify, sizeof(NOTIFY)))
837            {
838                    /*printf("disk_check_notify found changed event\n");*/
839                    memcpy(&pfinfo->notify, &notify, sizeof(NOTIFY));
840                    status = STATUS_NOTIFY_ENUM_DIR;
841            }
842    
843            return status;
844    
845    
846    }
847    
848    NTSTATUS
849    disk_create_notify(NTHANDLE handle, uint32 info_class)
850    {
851    
852            struct fileinfo *pfinfo;
853            NTSTATUS ret = STATUS_PENDING;
854    
855            /* printf("start disk_create_notify info_class %X\n", info_class); */
856    
857            pfinfo = &(g_fileinfo[handle]);
858            pfinfo->info_class = info_class;
859    
860            ret = NotifyInfo(handle, info_class, &pfinfo->notify);
861    
862            if (info_class & 0x1000)
863            {                       /* ???? */
864                    if (ret == STATUS_PENDING)
865                            return STATUS_SUCCESS;
866            }
867    
868            /* printf("disk_create_notify: num_entries %d\n", pfinfo->notify.num_entries); */
869    
870    
871            return ret;
872    
873    }
874    
875    static NTSTATUS
876    NotifyInfo(NTHANDLE handle, uint32 info_class, NOTIFY * p)
877    {
878            struct fileinfo *pfinfo;
879            struct stat buf;
880            struct dirent *dp;
881            char *fullname;
882            DIR *dpr;
883    
884            pfinfo = &(g_fileinfo[handle]);
885            if (fstat(handle, &buf) < 0)
886            {
887                    perror("NotifyInfo");
888                    return STATUS_ACCESS_DENIED;
889            }
890            p->modify_time = buf.st_mtime;
891            p->status_time = buf.st_ctime;
892            p->num_entries = 0;
893            p->total_time = 0;
894    
895    
896            dpr = opendir(pfinfo->path);
897            if (!dpr)
898            {
899                    perror("NotifyInfo");
900                    return STATUS_ACCESS_DENIED;
901            }
902    
903    
904            while ((dp = readdir(dpr)))
905            {
906                    if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
907                            continue;
908                    p->num_entries++;
909                    fullname = xmalloc(strlen(pfinfo->path) + strlen(dp->d_name) + 2);
910                    sprintf(fullname, "%s/%s", pfinfo->path, dp->d_name);
911    
912                    if (!stat(fullname, &buf))
913                    {
914                            p->total_time += (buf.st_mtime + buf.st_ctime);
915                    }
916    
917                    xfree(fullname);
918            }
919            closedir(dpr);
920    
921            return STATUS_PENDING;
922    }
923    
924  static FsInfoType *  static FsInfoType *
925  FsVolumeInfo(char *fpath)  FsVolumeInfo(char *fpath)
926  {  {
927    
928            static FsInfoType info;
929  #ifdef HAVE_MNTENT_H  #ifdef HAVE_MNTENT_H
930          FILE *fdfs;          FILE *fdfs;
931          struct mntent *e;          struct mntent *e;
932          static FsInfoType info;  #endif
933    
934          /* initialize */          /* initialize */
935          memset(&info, 0, sizeof(info));          memset(&info, 0, sizeof(info));
936          strcpy(info.label, "RDESKTOP");          strcpy(info.label, "RDESKTOP");
937          strcpy(info.type, "RDPFS");          strcpy(info.type, "RDPFS");
938    
939    #ifdef HAVE_MNTENT_H
940          fdfs = setmntent(MNTENT_PATH, "r");          fdfs = setmntent(MNTENT_PATH, "r");
941          if (!fdfs)          if (!fdfs)
942                  return &info;                  return &info;
# Line 722  FsVolumeInfo(char *fpath) Line 970  FsVolumeInfo(char *fpath)
970                                                  read(fd, buf, sizeof(buf));                                                  read(fd, buf, sizeof(buf));
971                                                  strncpy(info.label, buf + 41, 32);                                                  strncpy(info.label, buf + 41, 32);
972                                                  info.label[32] = '\0';                                                  info.label[32] = '\0';
973                                                  //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]; */
974                                          }                                          }
975                                          close(fd);                                          close(fd);
976                                  }                                  }
# Line 731  FsVolumeInfo(char *fpath) Line 979  FsVolumeInfo(char *fpath)
979          }          }
980          endmntent(fdfs);          endmntent(fdfs);
981  #else  #else
         static FsInfoType info;  
   
982          /* initialize */          /* initialize */
983          memset(&info, 0, sizeof(info));          memset(&info, 0, sizeof(info));
984          strcpy(info.label, "RDESKTOP");          strcpy(info.label, "RDESKTOP");
# Line 744  FsVolumeInfo(char *fpath) Line 990  FsVolumeInfo(char *fpath)
990    
991    
992  NTSTATUS  NTSTATUS
993  disk_query_volume_information(HANDLE handle, uint32 info_class, STREAM out)  disk_query_volume_information(NTHANDLE handle, uint32 info_class, STREAM out)
994  {  {
995          struct STATFS_T stat_fs;          struct STATFS_T stat_fs;
996          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
# Line 809  disk_query_volume_information(HANDLE han Line 1055  disk_query_volume_information(HANDLE han
1055  }  }
1056    
1057  NTSTATUS  NTSTATUS
1058  disk_query_directory(HANDLE handle, uint32 info_class, char *pattern, STREAM out)  disk_query_directory(NTHANDLE handle, uint32 info_class, char *pattern, STREAM out)
1059  {  {
1060          uint32 file_attributes, ft_low, ft_high;          uint32 file_attributes, ft_low, ft_high;
1061          char *dirname, fullpath[256];          char *dirname, fullpath[256];
# Line 827  disk_query_directory(HANDLE handle, uint Line 1073  disk_query_directory(HANDLE handle, uint
1073          {          {
1074                  case FileBothDirectoryInformation:                  case FileBothDirectoryInformation:
1075    
1076                          // If a search pattern is received, remember this pattern, and restart search                          /* If a search pattern is received, remember this pattern, and restart search */
1077                          if (pattern[0] != 0)                          if (pattern[0] != 0)
1078                          {                          {
1079                                  strncpy(pfinfo->pattern, 1 + strrchr(pattern, '/'), 64);                                  strncpy(pfinfo->pattern, 1 + strrchr(pattern, '/'), 64);
1080                                  rewinddir(pdir);                                  rewinddir(pdir);
1081                          }                          }
1082    
1083                          // find next dirent matching pattern                          /* find next dirent matching pattern */
1084                          pdirent = readdir(pdir);                          pdirent = readdir(pdir);
1085                          while (pdirent && fnmatch(pfinfo->pattern, pdirent->d_name, 0) != 0)                          while (pdirent && fnmatch(pfinfo->pattern, pdirent->d_name, 0) != 0)
1086                                  pdirent = readdir(pdir);                                  pdirent = readdir(pdir);
# Line 842  disk_query_directory(HANDLE handle, uint Line 1088  disk_query_directory(HANDLE handle, uint
1088                          if (pdirent == NULL)                          if (pdirent == NULL)
1089                                  return STATUS_NO_MORE_FILES;                                  return STATUS_NO_MORE_FILES;
1090    
1091                          // Get information for directory entry                          /* Get information for directory entry */
1092                          sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);                          sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);
1093    
1094                          if (stat(fullpath, &fstat))                          if (stat(fullpath, &fstat))
# Line 873  disk_query_directory(HANDLE handle, uint Line 1119  disk_query_directory(HANDLE handle, uint
1119                          if (!(fstat.st_mode & S_IWUSR))                          if (!(fstat.st_mode & S_IWUSR))
1120                                  file_attributes |= FILE_ATTRIBUTE_READONLY;                                  file_attributes |= FILE_ATTRIBUTE_READONLY;
1121    
1122                          // Return requested information                          /* Return requested information */
1123                          out_uint8s(out, 8);     //unknown zero                          out_uint8s(out, 8);     /* unknown zero */
1124    
1125                          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);
1126                          out_uint32_le(out, ft_low);     // create time                          out_uint32_le(out, ft_low);     /* create time */
1127                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
1128    
1129                          seconds_since_1970_to_filetime(fstat.st_atime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(fstat.st_atime, &ft_high, &ft_low);
1130                          out_uint32_le(out, ft_low);     //last_access_time                          out_uint32_le(out, ft_low);     /* last_access_time */
1131                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
1132    
1133                          seconds_since_1970_to_filetime(fstat.st_mtime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(fstat.st_mtime, &ft_high, &ft_low);
1134                          out_uint32_le(out, ft_low);     //last_write_time                          out_uint32_le(out, ft_low);     /* last_write_time */
1135                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
1136    
1137                          seconds_since_1970_to_filetime(fstat.st_ctime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(fstat.st_ctime, &ft_high, &ft_low);
1138                          out_uint32_le(out, ft_low);     //change_write_time                          out_uint32_le(out, ft_low);     /* change_write_time */
1139                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
1140    
1141                          out_uint32_le(out, fstat.st_size);      //filesize low                          out_uint32_le(out, fstat.st_size);      /* filesize low */
1142                          out_uint32_le(out, 0);  //filesize high                          out_uint32_le(out, 0);  /* filesize high */
1143                          out_uint32_le(out, fstat.st_size);      //filesize low                          out_uint32_le(out, fstat.st_size);      /* filesize low */
1144                          out_uint32_le(out, 0);  //filesize high                          out_uint32_le(out, 0);  /* filesize high */
1145                          out_uint32_le(out, file_attributes);                          out_uint32_le(out, file_attributes);
1146                          out_uint8(out, 2 * strlen(pdirent->d_name) + 2);        //unicode length                          out_uint8(out, 2 * strlen(pdirent->d_name) + 2);        /* unicode length */
1147                          out_uint8s(out, 7);     //pad?                          out_uint8s(out, 7);     /* pad? */
1148                          out_uint8(out, 0);      //8.3 file length                          out_uint8(out, 0);      /* 8.3 file length */
1149                          out_uint8s(out, 2 * 12);        //8.3 unicode length                          out_uint8s(out, 2 * 12);        /* 8.3 unicode length */
1150                          rdp_out_unistr(out, pdirent->d_name, 2 * strlen(pdirent->d_name));                          rdp_out_unistr(out, pdirent->d_name, 2 * strlen(pdirent->d_name));
1151                          break;                          break;
1152    
# Line 919  disk_query_directory(HANDLE handle, uint Line 1165  disk_query_directory(HANDLE handle, uint
1165    
1166    
1167  static NTSTATUS  static NTSTATUS
1168  disk_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out)  disk_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
1169  {  {
         uint32 result;  
   
1170          if (((request >> 16) != 20) || ((request >> 16) != 9))          if (((request >> 16) != 20) || ((request >> 16) != 9))
1171                  return STATUS_INVALID_PARAMETER;                  return STATUS_INVALID_PARAMETER;
1172    
# Line 934  disk_device_control(HANDLE handle, uint3 Line 1178  disk_device_control(HANDLE handle, uint3
1178    
1179          switch (request)          switch (request)
1180          {          {
1181                  case 25:        // ?                  case 25:        /* ? */
1182                  case 42:        // ?                  case 42:        /* ? */
1183                  default:                  default:
1184                          unimpl("DISK IOCTL %d\n", request);                          unimpl("DISK IOCTL %d\n", request);
1185                          return STATUS_INVALID_PARAMETER;                          return STATUS_INVALID_PARAMETER;

Legend:
Removed from v.747  
changed lines
  Added in v.865

  ViewVC Help
Powered by ViewVC 1.1.26