/[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 787 by astrand, Thu Oct 21 08:28:03 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 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 191  ftruncate_growable(int fd, off_t length) Line 198  ftruncate_growable(int fd, off_t length)
198          return 0;          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 203  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 249  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 334  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 374  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;
# Line 389  disk_close(NTHANDLE handle) Line 452  disk_close(NTHANDLE handle)
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;
# Line 427  disk_read(NTHANDLE handle, uint8 * data, Line 517  disk_read(NTHANDLE handle, uint8 * data,
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 475  disk_query_information(NTHANDLE handle, Line 568  disk_query_information(NTHANDLE handle,
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 483  disk_query_information(NTHANDLE handle, Line 576  disk_query_information(NTHANDLE handle,
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 498  disk_query_information(NTHANDLE handle, Line 591  disk_query_information(NTHANDLE handle,
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 524  disk_query_information(NTHANDLE handle, Line 617  disk_query_information(NTHANDLE handle,
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 550  disk_query_information(NTHANDLE handle, Line 643  disk_query_information(NTHANDLE handle,
643  NTSTATUS  NTSTATUS
644  disk_set_information(NTHANDLE handle, uint32 info_class, STREAM in, STREAM out)  disk_set_information(NTHANDLE handle, uint32 info_class, STREAM in, STREAM out)
645  {  {
646          uint32 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 561  disk_set_information(NTHANDLE handle, ui Line 653  disk_set_information(NTHANDLE handle, ui
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 570  disk_set_information(NTHANDLE handle, ui Line 663  disk_set_information(NTHANDLE handle, ui
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 620  disk_set_information(NTHANDLE handle, ui Line 713  disk_set_information(NTHANDLE handle, ui
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 678  disk_set_information(NTHANDLE handle, ui Line 771  disk_set_information(NTHANDLE handle, ui
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. */  
   
                         //in_uint32_le(in, delete_on_close);  
775    
776                          /* Make sure we close the file before                          in_uint32_le(in, delete_on_close);
                            unlinking it. Not doing so would trigger  
                            silly-delete if using NFS, which might fail  
                            on FAT floppies, for example. */  
                         disk_close(handle);  
777    
778                          if ((pfinfo->flags_and_attributes & FILE_DIRECTORY_FILE))       // remove a directory                          if (delete_on_close ||
779                                (pfinfo->
780                                 accessmask & (FILE_DELETE_ON_CLOSE | FILE_COMPLETE_IF_OPLOCKED)))
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 713  disk_set_information(NTHANDLE handle, ui Line 797  disk_set_information(NTHANDLE handle, ui
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                          if (ftruncate_growable(handle, length) != 0)                          if (ftruncate_growable(handle, length) != 0)
# Line 730  disk_set_information(NTHANDLE handle, ui Line 814  disk_set_information(NTHANDLE handle, ui
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 777  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 786  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 882  disk_query_directory(NTHANDLE handle, ui Line 1073  disk_query_directory(NTHANDLE handle, ui
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 897  disk_query_directory(NTHANDLE handle, ui Line 1088  disk_query_directory(NTHANDLE handle, ui
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 928  disk_query_directory(NTHANDLE handle, ui Line 1119  disk_query_directory(NTHANDLE handle, ui
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 987  disk_device_control(NTHANDLE handle, uin Line 1178  disk_device_control(NTHANDLE handle, uin
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.787  
changed lines
  Added in v.865

  ViewVC Help
Powered by ViewVC 1.1.26