/[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 653 by astrand, Thu Apr 15 20:53:32 2004 UTC revision 807 by stargo, Thu Dec 23 20:43:47 2004 UTC
# Line 20  Line 20 
20    
21  #include "disk.h"  #include "disk.h"
22    
 #if (defined(sun) && (defined(__svr4__) || defined(__SVR4)))  
 #define SOLARIS  
 #endif  
   
 #if (defined(SOLARIS) || defined(__hpux))  
 #define DIRFD(a) ((a)->dd_fd)  
 #else  
 #define DIRFD(a) (dirfd(a))  
 #endif  
   
23  #include <sys/types.h>  #include <sys/types.h>
24  #include <sys/stat.h>  #include <sys/stat.h>
25  #include <unistd.h>  #include <unistd.h>
# Line 41  Line 31 
31  #include <utime.h>  #include <utime.h>
32  #include <time.h>               /* ctime */  #include <time.h>               /* ctime */
33    
34    #if (defined(HAVE_DIRFD) || (HAVE_DECL_DIRFD == 1))
35    #define DIRFD(a) (dirfd(a))
36    #else
37    #define DIRFD(a) ((a)->DIR_FD_MEMBER_NAME)
38    #endif
39    
40    /* TODO: let autoconf figure out everything below... */
41    #if (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
42    #define SOLARIS
43    #endif
44    
45  #if (defined(SOLARIS) || defined (__hpux) || defined(__BEOS__))  #if (defined(SOLARIS) || defined (__hpux) || defined(__BEOS__))
46  #include <sys/statvfs.h>        /* solaris statvfs */  #include <sys/statvfs.h>        /* solaris statvfs */
47  #include <sys/mntent.h>  /* TODO: Fix mntent-handling for solaris/hpux
48  /* TODO: Fix mntent-handling for solaris */   * #include <sys/mntent.h> */
49  #undef HAVE_MNTENT_H  #undef HAVE_MNTENT_H
50  #define MNTENT_PATH "/etc/mnttab"  #define MNTENT_PATH "/etc/mnttab"
51  #define STATFS_FN(path, buf) (statvfs(path,buf))  #define STATFS_FN(path, buf) (statvfs(path,buf))
52  #define STATFS_T statvfs  #define STATFS_T statvfs
53  #define F_NAMELEN(buf) ((buf).f_namemax)  #define F_NAMELEN(buf) ((buf).f_namemax)
54    
55  #elif (defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__))  #elif (defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__APPLE__))
56  #include <sys/param.h>  #include <sys/param.h>
57  #include <sys/mount.h>  #include <sys/mount.h>
58  #define STATFS_FN(path, buf) (statfs(path,buf))  #define STATFS_FN(path, buf) (statfs(path,buf))
59  #define STATFS_T statfs  #define STATFS_T statfs
60  #define F_NAMELEN(buf) (NAME_MAX)  #define F_NAMELEN(buf) (NAME_MAX)
61    
62    #elif (defined(__SGI_IRIX__))
63    #include <sys/types.h>
64    #include <sys/statvfs.h>
65    #define STATFS_FN(path, buf) (statvfs(path,buf))
66    #define STATFS_T statvfs
67    #define F_NAMELEN(buf) ((buf).f_namemax)
68    
69    #elif (defined(__alpha) && !defined(linux))
70    #include <sys/mount.h>                /* osf1 statfs */
71    #define STATFS_FN(path, buf) (statfs(path,buf,sizeof(buf)))
72    #define STATFS_T statfs
73    #define F_NAMELEN(buf) (255)
74    
75  #else  #else
76  #include <sys/vfs.h>            /* linux statfs */  #include <sys/vfs.h>            /* linux statfs */
77  #include <mntent.h>  #include <mntent.h>
# Line 74  Line 87 
87  extern RDPDR_DEVICE g_rdpdr_device[];  extern RDPDR_DEVICE g_rdpdr_device[];
88    
89  FILEINFO g_fileinfo[MAX_OPEN_FILES];  FILEINFO g_fileinfo[MAX_OPEN_FILES];
90    BOOL g_notify_stamp = False;
91    
92  typedef struct  typedef struct
93  {  {
# Line 83  typedef struct Line 97  typedef struct
97          char type[256];          char type[256];
98  } FsInfoType;  } FsInfoType;
99    
100    static NTSTATUS NotifyInfo(NTHANDLE handle, uint32 info_class, NOTIFY * p);
101    
102  time_t  static time_t
103  get_create_time(struct stat *st)  get_create_time(struct stat *st)
104  {  {
105          time_t ret, ret1;          time_t ret, ret1;
# Line 99  get_create_time(struct stat *st) Line 114  get_create_time(struct stat *st)
114  }  }
115    
116  /* Convert seconds since 1970 to a filetime */  /* Convert seconds since 1970 to a filetime */
117  void  static void
118  seconds_since_1970_to_filetime(time_t seconds, uint32 * high, uint32 * low)  seconds_since_1970_to_filetime(time_t seconds, uint32 * high, uint32 * low)
119  {  {
120          unsigned long long ticks;          unsigned long long ticks;
# Line 110  seconds_since_1970_to_filetime(time_t se Line 125  seconds_since_1970_to_filetime(time_t se
125  }  }
126    
127  /* Convert seconds since 1970 back to filetime */  /* Convert seconds since 1970 back to filetime */
128  time_t  static time_t
129  convert_1970_to_filetime(uint32 high, uint32 low)  convert_1970_to_filetime(uint32 high, uint32 low)
130  {  {
131          unsigned long long ticks;          unsigned long long ticks;
# Line 125  convert_1970_to_filetime(uint32 high, ui Line 140  convert_1970_to_filetime(uint32 high, ui
140    
141  }  }
142    
143    /* A wrapper for ftruncate which supports growing files, even if the
144       native ftruncate doesn't. This is needed on Linux FAT filesystems,
145       for example. */
146    static int
147    ftruncate_growable(int fd, off_t length)
148    {
149            int ret;
150            off_t pos;
151            static const char zero;
152    
153            /* Try the simple method first */
154            if ((ret = ftruncate(fd, length)) != -1)
155            {
156                    return ret;
157            }
158    
159            /*
160             * Some kind of error. Perhaps we were trying to grow. Retry
161             * in a safe way.
162             */
163    
164            /* Get current position */
165            if ((pos = lseek(fd, 0, SEEK_CUR)) == -1)
166            {
167                    perror("lseek");
168                    return -1;
169            }
170    
171            /* Seek to new size */
172            if (lseek(fd, length, SEEK_SET) == -1)
173            {
174                    perror("lseek");
175                    return -1;
176            }
177    
178            /* Write a zero */
179            if (write(fd, &zero, 1) == -1)
180            {
181                    perror("write");
182                    return -1;
183            }
184    
185            /* Truncate. This shouldn't fail. */
186            if (ftruncate(fd, length) == -1)
187            {
188                    perror("ftruncate");
189                    return -1;
190            }
191    
192            /* Restore position */
193            if (lseek(fd, pos, SEEK_SET) == -1)
194            {
195                    perror("lseek");
196                    return -1;
197            }
198    
199            return 0;
200    }
201    
202    /* Just like open(2), but if a open with O_EXCL fails, retry with
203       GUARDED semantics. This might be necessary because some filesystems
204       (such as NFS filesystems mounted from a unfsd server) doesn't
205       support O_EXCL. GUARDED semantics are subject to race conditions,
206       but we can live with that.
207    */
208    static int
209    open_weak_exclusive(const char *pathname, int flags, mode_t mode)
210    {
211            int ret;
212            struct stat statbuf;
213    
214            ret = open(pathname, flags, mode);
215            if (ret != -1 || !(flags & O_EXCL))
216            {
217                    /* Success, or not using O_EXCL */
218                    return ret;
219            }
220    
221            /* An error occured, and we are using O_EXCL. In case the FS
222               doesn't support O_EXCL, some kind of error will be
223               returned. Unfortunately, we don't know which one. Linux
224               2.6.8 seems to return 524, but I cannot find a documented
225               #define for this case. So, we'll return only on errors that
226               we know aren't related to O_EXCL. */
227            switch (errno)
228            {
229                    case EACCES:
230                    case EEXIST:
231                    case EINTR:
232                    case EISDIR:
233                    case ELOOP:
234                    case ENAMETOOLONG:
235                    case ENOENT:
236                    case ENOTDIR:
237                            return ret;
238            }
239    
240            /* Retry with GUARDED semantics */
241            if (stat(pathname, &statbuf) != -1)
242            {
243                    /* File exists */
244                    errno = EEXIST;
245                    return -1;
246            }
247            else
248            {
249                    return open(pathname, flags & ~O_EXCL, mode);
250            }
251    }
252    
253  /* Enumeration of devices from rdesktop.c        */  /* Enumeration of devices from rdesktop.c        */
254  /* returns numer of units found and initialized. */  /* returns numer of units found and initialized. */
# Line 142  disk_enum_devices(uint32 * id, char *opt Line 266  disk_enum_devices(uint32 * id, char *opt
266          while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)          while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)
267          {          {
268                  pos2 = next_arg(optarg, '=');                  pos2 = next_arg(optarg, '=');
                 strcpy(g_rdpdr_device[*id].name, optarg);  
   
                 toupper_str(g_rdpdr_device[*id].name);  
269    
270                  /* add trailing colon to name. */                  strncpy(g_rdpdr_device[*id].name, optarg, sizeof(g_rdpdr_device[*id].name));
271                  strcat(g_rdpdr_device[*id].name, ":");                  if (strlen(optarg) > 8)
272                            fprintf(stderr, "share name %s truncated to %s\n", optarg,
273                                    g_rdpdr_device[*id].name);
274    
275                  g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);                  g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);
276                  strcpy(g_rdpdr_device[*id].local_path, pos2);                  strcpy(g_rdpdr_device[*id].local_path, pos2);
                 printf("DISK %s to %s\n", g_rdpdr_device[*id].name, g_rdpdr_device[*id].local_path);  
277                  g_rdpdr_device[*id].device_type = DEVICE_TYPE_DISK;                  g_rdpdr_device[*id].device_type = DEVICE_TYPE_DISK;
278                  count++;                  count++;
279                  (*id)++;                  (*id)++;
# Line 162  disk_enum_devices(uint32 * id, char *opt Line 284  disk_enum_devices(uint32 * id, char *opt
284  }  }
285    
286  /* Opens or creates a file or directory */  /* Opens or creates a file or directory */
287  NTSTATUS  static NTSTATUS
288  disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition,  disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition,
289              uint32 flags_and_attributes, char *filename, HANDLE * phandle)              uint32 flags_and_attributes, char *filename, NTHANDLE * phandle)
290  {  {
291          HANDLE handle;          NTHANDLE handle;
292          DIR *dirp;          DIR *dirp;
293          int flags, mode;          int flags, mode;
294          char path[256];          char path[256];
# Line 177  disk_create(uint32 device_id, uint32 acc Line 299  disk_create(uint32 device_id, uint32 acc
299          flags = 0;          flags = 0;
300          mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;          mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
301    
302            if (*filename && filename[strlen(filename) - 1] == '/')
         if (filename[strlen(filename) - 1] == '/')  
303                  filename[strlen(filename) - 1] = 0;                  filename[strlen(filename) - 1] = 0;
304          sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename);          sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename);
305    
# Line 215  disk_create(uint32 device_id, uint32 acc Line 336  disk_create(uint32 device_id, uint32 acc
336                          break;                          break;
337          }          }
338    
339          //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);
340    
341          // Get information about file and set that flag ourselfs          // Get information about file and set that flag ourselfs
342          if ((stat(path, &filestat) == 0) && (S_ISDIR(filestat.st_mode)))          if ((stat(path, &filestat) == 0) && (S_ISDIR(filestat.st_mode)))
# Line 271  disk_create(uint32 device_id, uint32 acc Line 392  disk_create(uint32 device_id, uint32 acc
392                          flags |= O_RDONLY;                          flags |= O_RDONLY;
393                  }                  }
394    
395                  handle = open(path, flags, mode);                  handle = open_weak_exclusive(path, flags, mode);
396                  if (handle == -1)                  if (handle == -1)
397                  {                  {
398                          switch (errno)                          switch (errno)
# Line 311  disk_create(uint32 device_id, uint32 acc Line 432  disk_create(uint32 device_id, uint32 acc
432    
433          if (dirp)          if (dirp)
434                  g_fileinfo[handle].pdir = dirp;                  g_fileinfo[handle].pdir = dirp;
435            else
436                    g_fileinfo[handle].pdir = NULL;
437    
438          g_fileinfo[handle].device_id = device_id;          g_fileinfo[handle].device_id = device_id;
439          g_fileinfo[handle].flags_and_attributes = flags_and_attributes;          g_fileinfo[handle].flags_and_attributes = flags_and_attributes;
440            g_fileinfo[handle].accessmask = accessmask;
441          strncpy(g_fileinfo[handle].path, path, 255);          strncpy(g_fileinfo[handle].path, path, 255);
442            g_fileinfo[handle].delete_on_close = False;
443            g_notify_stamp = True;
444    
445          *phandle = handle;          *phandle = handle;
446          return STATUS_SUCCESS;          return STATUS_SUCCESS;
447  }  }
448    
449  NTSTATUS  static NTSTATUS
450  disk_close(HANDLE handle)  disk_close(NTHANDLE handle)
451  {  {
452          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
453    
454          pfinfo = &(g_fileinfo[handle]);          pfinfo = &(g_fileinfo[handle]);
455    
456          if (pfinfo->flags_and_attributes & FILE_DIRECTORY_FILE)          g_notify_stamp = True;
457    
458            rdpdr_abort_io(handle, 0, STATUS_CANCELLED);
459    
460            if (pfinfo->pdir)
461          {          {
462                  closedir(pfinfo->pdir);                  if (closedir(pfinfo->pdir) < 0)
463                  //FIXME: Should check exit code                  {
464                            perror("closedir");
465                            return STATUS_INVALID_HANDLE;
466                    }
467    
468                    if (pfinfo->delete_on_close)
469                            if (rmdir(pfinfo->path) < 0)
470                            {
471                                    perror(pfinfo->path);
472                                    return STATUS_ACCESS_DENIED;
473                            }
474                    pfinfo->delete_on_close = False;
475          }          }
476          else          else
477          {          {
478                  close(handle);                  if (close(handle) < 0)
479                    {
480                            perror("close");
481                            return STATUS_INVALID_HANDLE;
482                    }
483                    if (pfinfo->delete_on_close)
484                            if (unlink(pfinfo->path) < 0)
485                            {
486                                    perror(pfinfo->path);
487                                    return STATUS_ACCESS_DENIED;
488                            }
489    
490                    pfinfo->delete_on_close = False;
491          }          }
492    
493          return STATUS_SUCCESS;          return STATUS_SUCCESS;
494  }  }
495    
496  NTSTATUS  static NTSTATUS
497  disk_read(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  disk_read(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
498  {  {
499          int n;          int n;
500    
# Line 364  disk_read(HANDLE handle, uint8 * data, u Line 518  disk_read(HANDLE handle, uint8 * data, u
518                  switch (errno)                  switch (errno)
519                  {                  {
520                          case EISDIR:                          case EISDIR:
521                                  return STATUS_FILE_IS_A_DIRECTORY;                                  /* Implement 24 Byte directory read ??
522                                       with STATUS_NOT_IMPLEMENTED server doesn't read again */
523                                    /* return STATUS_FILE_IS_A_DIRECTORY; */
524                                    return STATUS_NOT_IMPLEMENTED;
525                          default:                          default:
526                                  perror("read");                                  perror("read");
527                                  return STATUS_INVALID_PARAMETER;                                  return STATUS_INVALID_PARAMETER;
# Line 376  disk_read(HANDLE handle, uint8 * data, u Line 533  disk_read(HANDLE handle, uint8 * data, u
533          return STATUS_SUCCESS;          return STATUS_SUCCESS;
534  }  }
535    
536  NTSTATUS  static NTSTATUS
537  disk_write(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  disk_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
538  {  {
539          int n;          int n;
540    
# Line 404  disk_write(HANDLE handle, uint8 * data, Line 561  disk_write(HANDLE handle, uint8 * data,
561  }  }
562    
563  NTSTATUS  NTSTATUS
564  disk_query_information(HANDLE handle, uint32 info_class, STREAM out)  disk_query_information(NTHANDLE handle, uint32 info_class, STREAM out)
565  {  {
566          uint32 file_attributes, ft_high, ft_low;          uint32 file_attributes, ft_high, ft_low;
567          struct stat filestat;          struct stat filestat;
# Line 485  disk_query_information(HANDLE handle, ui Line 642  disk_query_information(HANDLE handle, ui
642  }  }
643    
644  NTSTATUS  NTSTATUS
645  disk_set_information(HANDLE handle, uint32 info_class, STREAM in, STREAM out)  disk_set_information(NTHANDLE handle, uint32 info_class, STREAM in, STREAM out)
646  {  {
647          uint32 device_id, length, file_attributes, ft_high, ft_low;          uint32 length, file_attributes, ft_high, ft_low, delete_on_close;
648          char newname[256], fullpath[256];          char newname[256], fullpath[256];
649          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
   
650          int mode;          int mode;
651          struct stat filestat;          struct stat filestat;
652          time_t write_time, change_time, access_time, mod_time;          time_t write_time, change_time, access_time, mod_time;
# Line 498  disk_set_information(HANDLE handle, uint Line 654  disk_set_information(HANDLE handle, uint
654          struct STATFS_T stat_fs;          struct STATFS_T stat_fs;
655    
656          pfinfo = &(g_fileinfo[handle]);          pfinfo = &(g_fileinfo[handle]);
657            g_notify_stamp = True;
658    
659          switch (info_class)          switch (info_class)
660          {          {
# Line 557  disk_set_information(HANDLE handle, uint Line 714  disk_set_information(HANDLE handle, uint
714                                  printf("FileBasicInformation modification time %s",                                  printf("FileBasicInformation modification time %s",
715                                         ctime(&tvs.modtime));                                         ctime(&tvs.modtime));
716  #endif  #endif
717                                  if (utime(pfinfo->path, &tvs))                                  if (utime(pfinfo->path, &tvs) && errno != EPERM)
718                                          return STATUS_ACCESS_DENIED;                                          return STATUS_ACCESS_DENIED;
719                          }                          }
720    
# Line 608  disk_set_information(HANDLE handle, uint Line 765  disk_set_information(HANDLE handle, uint
765                          break;                          break;
766    
767                  case FileDispositionInformation:                  case FileDispositionInformation:
768                            /* As far as I understand it, the correct
769                          //unimpl("IRP Set File Information class: FileDispositionInformation\n");                             thing to do here is to *schedule* a delete,
770                               so it will be deleted when the file is
771                          //in_uint32_le(in, delete_on_close);                             closed. Subsequent
772                          // disk_close(handle);                             FileDispositionInformation requests with
773                          if ((pfinfo->flags_and_attributes & FILE_DIRECTORY_FILE))       // remove a directory                             DeleteFile set to FALSE should unschedule
774                               the delete. See
775                               http://www.osronline.com/article.cfm?article=245. */
776    
777                            in_uint32_le(in, delete_on_close);
778    
779                            if (delete_on_close ||
780                                (pfinfo->
781                                 accessmask & (FILE_DELETE_ON_CLOSE | FILE_COMPLETE_IF_OPLOCKED)))
782                          {                          {
783                                  if (rmdir(pfinfo->path) < 0)                                  pfinfo->delete_on_close = True;
                                         return STATUS_ACCESS_DENIED;  
784                          }                          }
                         else if (unlink(pfinfo->path) < 0)      // unlink a file  
                                 return STATUS_ACCESS_DENIED;  
785    
786                          break;                          break;
787    
788                  case FileAllocationInformation:                  case FileAllocationInformation:
789                            /* Fall through to FileEndOfFileInformation,
790                          unimpl("IRP Set File Information class: FileAllocationInformation\n");                             which uses ftrunc. This is like Samba with
791                          break;                             "strict allocation = false", and means that
792                               we won't detect out-of-quota errors, for
793                               example. */
794    
795                  case FileEndOfFileInformation:                  case FileEndOfFileInformation:
796                          in_uint8s(in, 28);      /* unknown */                          in_uint8s(in, 28);      /* unknown */
# Line 634  disk_set_information(HANDLE handle, uint Line 798  disk_set_information(HANDLE handle, uint
798    
799                          /* prevents start of writing if not enough space left on device */                          /* prevents start of writing if not enough space left on device */
800                          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)
801                                  if (stat_fs.f_bsize * stat_fs.f_bfree < length)                                  if (stat_fs.f_bfree * stat_fs.f_bsize < length)
802                                          return STATUS_DISK_FULL;                                          return STATUS_DISK_FULL;
803    
804                          //printf("FileEndOfFileInformation length = %d\n", length);                          if (ftruncate_growable(handle, length) != 0)
805                          // ????????????                          {
806                          //unimpl("IRP Set File Information class: FileEndOfFileInformation\n");                                  return STATUS_DISK_FULL;
807                            }
808    
809                          break;                          break;
810                  default:                  default:
811    
# Line 649  disk_set_information(HANDLE handle, uint Line 815  disk_set_information(HANDLE handle, uint
815          return STATUS_SUCCESS;          return STATUS_SUCCESS;
816  }  }
817    
818  FsInfoType *  NTSTATUS
819    disk_check_notify(NTHANDLE handle)
820    {
821            struct fileinfo *pfinfo;
822            NTSTATUS status = STATUS_PENDING;
823    
824            NOTIFY notify;
825    
826            pfinfo = &(g_fileinfo[handle]);
827            if (!pfinfo->pdir)
828                    return STATUS_INVALID_DEVICE_REQUEST;
829    
830    
831    
832            status = NotifyInfo(handle, pfinfo->info_class, &notify);
833    
834            if (status != STATUS_PENDING)
835                    return status;
836    
837            if (memcmp(&pfinfo->notify, &notify, sizeof(NOTIFY)))
838            {
839                    //printf("disk_check_notify found changed event\n");
840                    memcpy(&pfinfo->notify, &notify, sizeof(NOTIFY));
841                    status = STATUS_NOTIFY_ENUM_DIR;
842            }
843    
844            return status;
845    
846    
847    }
848    
849    NTSTATUS
850    disk_create_notify(NTHANDLE handle, uint32 info_class)
851    {
852    
853            struct fileinfo *pfinfo;
854            NTSTATUS ret = STATUS_PENDING;
855    
856            /* printf("start disk_create_notify info_class %X\n", info_class); */
857    
858            pfinfo = &(g_fileinfo[handle]);
859            pfinfo->info_class = info_class;
860    
861            ret = NotifyInfo(handle, info_class, &pfinfo->notify);
862    
863            if (info_class & 0x1000)
864            {                       /* ???? */
865                    if (ret == STATUS_PENDING)
866                            return STATUS_SUCCESS;
867            }
868    
869            /* printf("disk_create_notify: num_entries %d\n", pfinfo->notify.num_entries); */
870    
871    
872            return ret;
873    
874    }
875    
876    static NTSTATUS
877    NotifyInfo(NTHANDLE handle, uint32 info_class, NOTIFY * p)
878    {
879            struct fileinfo *pfinfo;
880            struct stat buf;
881            struct dirent *dp;
882            char *fullname;
883            DIR *dpr;
884    
885            pfinfo = &(g_fileinfo[handle]);
886            if (fstat(handle, &buf) < 0)
887            {
888                    perror("NotifyInfo");
889                    return STATUS_ACCESS_DENIED;
890            }
891            p->modify_time = buf.st_mtime;
892            p->status_time = buf.st_ctime;
893            p->num_entries = 0;
894            p->total_time = 0;
895    
896    
897            dpr = opendir(pfinfo->path);
898            if (!dpr)
899            {
900                    perror("NotifyInfo");
901                    return STATUS_ACCESS_DENIED;
902            }
903    
904    
905            while ((dp = readdir(dpr)))
906            {
907                    if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
908                            continue;
909                    p->num_entries++;
910                    fullname = xmalloc(strlen(pfinfo->path) + strlen(dp->d_name) + 2);
911                    sprintf(fullname, "%s/%s", pfinfo->path, dp->d_name);
912    
913                    if (!stat(fullname, &buf))
914                    {
915                            p->total_time += (buf.st_mtime + buf.st_ctime);
916                    }
917    
918                    xfree(fullname);
919            }
920            closedir(dpr);
921    
922            return STATUS_PENDING;
923    }
924    
925    static FsInfoType *
926  FsVolumeInfo(char *fpath)  FsVolumeInfo(char *fpath)
927  {  {
928    
 #ifdef HAVE_MNTENT_H  
929          FILE *fdfs;          FILE *fdfs;
         struct mntent *e;  
930          static FsInfoType info;          static FsInfoType info;
931    #ifdef HAVE_MNTENT_H
932            struct mntent *e;
933    #endif
934    
935          /* initialize */          /* initialize */
936          memset(&info, 0, sizeof(info));          memset(&info, 0, sizeof(info));
937          strcpy(info.label, "RDESKTOP");          strcpy(info.label, "RDESKTOP");
938          strcpy(info.type, "RDPFS");          strcpy(info.type, "RDPFS");
939    
940    #ifdef HAVE_MNTENT_H
941          fdfs = setmntent(MNTENT_PATH, "r");          fdfs = setmntent(MNTENT_PATH, "r");
942          if (!fdfs)          if (!fdfs)
943                  return &info;                  return &info;
# Line 705  FsVolumeInfo(char *fpath) Line 980  FsVolumeInfo(char *fpath)
980          }          }
981          endmntent(fdfs);          endmntent(fdfs);
982  #else  #else
         static FsInfoType info;  
   
983          /* initialize */          /* initialize */
984          memset(&info, 0, sizeof(info));          memset(&info, 0, sizeof(info));
985          strcpy(info.label, "RDESKTOP");          strcpy(info.label, "RDESKTOP");
# Line 718  FsVolumeInfo(char *fpath) Line 991  FsVolumeInfo(char *fpath)
991    
992    
993  NTSTATUS  NTSTATUS
994  disk_query_volume_information(HANDLE handle, uint32 info_class, STREAM out)  disk_query_volume_information(NTHANDLE handle, uint32 info_class, STREAM out)
995  {  {
996          struct STATFS_T stat_fs;          struct STATFS_T stat_fs;
997          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
# Line 783  disk_query_volume_information(HANDLE han Line 1056  disk_query_volume_information(HANDLE han
1056  }  }
1057    
1058  NTSTATUS  NTSTATUS
1059  disk_query_directory(HANDLE handle, uint32 info_class, char *pattern, STREAM out)  disk_query_directory(NTHANDLE handle, uint32 info_class, char *pattern, STREAM out)
1060  {  {
1061          uint32 file_attributes, ft_low, ft_high;          uint32 file_attributes, ft_low, ft_high;
1062          char *dirname, fullpath[256];          char *dirname, fullpath[256];
# Line 799  disk_query_directory(HANDLE handle, uint Line 1072  disk_query_directory(HANDLE handle, uint
1072    
1073          switch (info_class)          switch (info_class)
1074          {          {
1075                  case 3: //FIXME: Why 3?                  case FileBothDirectoryInformation:
1076    
1077                          // If a search pattern is received, remember this pattern, and restart search                          // If a search pattern is received, remember this pattern, and restart search
1078                          if (pattern[0] != 0)                          if (pattern[0] != 0)
# Line 819  disk_query_directory(HANDLE handle, uint Line 1092  disk_query_directory(HANDLE handle, uint
1092                          // Get information for directory entry                          // Get information for directory entry
1093                          sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);                          sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);
1094    
                         /* JIF  
                            printf("Stat: %s\n", fullpath); */  
1095                          if (stat(fullpath, &fstat))                          if (stat(fullpath, &fstat))
1096                          {                          {
1097                                  perror("stat");                                  switch (errno)
1098                                  out_uint8(out, 0);                                  {
1099                                  return STATUS_ACCESS_DENIED;                                          case ENOENT:
1100                                            case ELOOP:
1101                                            case EACCES:
1102                                                    /* These are non-fatal errors. */
1103                                                    memset(&fstat, 0, sizeof(fstat));
1104                                                    break;
1105                                            default:
1106                                                    /* Fatal error. By returning STATUS_NO_SUCH_FILE,
1107                                                       the directory list operation will be aborted */
1108                                                    perror(fullpath);
1109                                                    out_uint8(out, 0);
1110                                                    return STATUS_NO_SUCH_FILE;
1111                                    }
1112                          }                          }
1113    
1114                          if (S_ISDIR(fstat.st_mode))                          if (S_ISDIR(fstat.st_mode))
# Line 869  disk_query_directory(HANDLE handle, uint Line 1152  disk_query_directory(HANDLE handle, uint
1152                          break;                          break;
1153    
1154                  default:                  default:
1155                            /* FIXME: Support FileDirectoryInformation,
1156                               FileFullDirectoryInformation, and
1157                               FileNamesInformation */
1158    
1159                          unimpl("IRP Query Directory sub: 0x%x\n", info_class);                          unimpl("IRP Query Directory sub: 0x%x\n", info_class);
1160                          return STATUS_INVALID_PARAMETER;                          return STATUS_INVALID_PARAMETER;
# Line 880  disk_query_directory(HANDLE handle, uint Line 1166  disk_query_directory(HANDLE handle, uint
1166    
1167    
1168  static NTSTATUS  static NTSTATUS
1169  disk_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out)  disk_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
1170  {  {
         uint32 result;  
   
1171          if (((request >> 16) != 20) || ((request >> 16) != 9))          if (((request >> 16) != 20) || ((request >> 16) != 9))
1172                  return STATUS_INVALID_PARAMETER;                  return STATUS_INVALID_PARAMETER;
1173    

Legend:
Removed from v.653  
changed lines
  Added in v.807

  ViewVC Help
Powered by ViewVC 1.1.26