/[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 686 by stargo, Thu Apr 29 19:41:49 2004 UTC revision 827 by astrand, Thu Mar 3 08:48:24 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    
 #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  
   
24  #include <sys/types.h>  #include <sys/types.h>
25  #include <sys/stat.h>  #include <sys/stat.h>
26  #include <unistd.h>  #include <unistd.h>
# Line 41  Line 32 
32  #include <utime.h>  #include <utime.h>
33  #include <time.h>               /* ctime */  #include <time.h>               /* ctime */
34    
35    #if (defined(HAVE_DIRFD) || (HAVE_DECL_DIRFD == 1))
36    #define DIRFD(a) (dirfd(a))
37    #else
38    #define DIRFD(a) ((a)->DIR_FD_MEMBER_NAME)
39    #endif
40    
41    /* TODO: let autoconf figure out everything below... */
42    #if (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
43    #define SOLARIS
44    #endif
45    
46  #if (defined(SOLARIS) || defined (__hpux) || defined(__BEOS__))  #if (defined(SOLARIS) || defined (__hpux) || defined(__BEOS__))
47  #include <sys/statvfs.h>        /* solaris statvfs */  #include <sys/statvfs.h>        /* solaris statvfs */
# 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))
60  #define STATFS_T statfs  #define STATFS_T statfs
61  #define F_NAMELEN(buf) (NAME_MAX)  #define F_NAMELEN(buf) (NAME_MAX)
62    
63    #elif (defined(__SGI_IRIX__))
64    #include <sys/types.h>
65    #include <sys/statvfs.h>
66    #define STATFS_FN(path, buf) (statvfs(path,buf))
67    #define STATFS_T statvfs
68    #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 69  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 83  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 125  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 142  disk_enum_devices(uint32 * id, char *opt Line 265  disk_enum_devices(uint32 * id, char *opt
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, '=');
                 strcpy(g_rdpdr_device[*id].name, optarg);  
   
                 toupper_str(g_rdpdr_device[*id].name);  
268    
269                  /* add trailing colon to name. */                  strncpy(g_rdpdr_device[*id].name, optarg, sizeof(g_rdpdr_device[*id].name) - 1);
270                  strcat(g_rdpdr_device[*id].name, ":");                  if (strlen(optarg) > (sizeof(g_rdpdr_device[*id].name) - 1))
271                            fprintf(stderr, "share name %s truncated to %s\n", optarg,
272                                    g_rdpdr_device[*id].name);
273    
274                  g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);                  g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);
275                  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);  
276                  g_rdpdr_device[*id].device_type = DEVICE_TYPE_DISK;                  g_rdpdr_device[*id].device_type = DEVICE_TYPE_DISK;
277                  count++;                  count++;
278                  (*id)++;                  (*id)++;
# Line 164  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 177  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 215  disk_create(uint32 device_id, uint32 acc Line 335  disk_create(uint32 device_id, uint32 acc
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)))
# Line 271  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 311  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 364  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 377  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 404  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 485  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 498  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 557  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    
# Line 615  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. */  
   
                         //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 650  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                          if (ftruncate(handle, length) != 0)                          if (ftruncate_growable(handle, length) != 0)
804                          {                          {
                                 perror("ftruncate");  
805                                  return STATUS_DISK_FULL;                                  return STATUS_DISK_FULL;
806                          }                          }
807    
# Line 668  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    
 #ifdef HAVE_MNTENT_H  
928          FILE *fdfs;          FILE *fdfs;
         struct mntent *e;  
929          static FsInfoType info;          static FsInfoType info;
930    #ifdef HAVE_MNTENT_H
931            struct mntent *e;
932    #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 724  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 737  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 802  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 818  disk_query_directory(HANDLE handle, uint Line 1071  disk_query_directory(HANDLE handle, uint
1071    
1072          switch (info_class)          switch (info_class)
1073          {          {
1074                  case 3: //FIXME: Why 3?                  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)
# Line 838  disk_query_directory(HANDLE handle, uint Line 1091  disk_query_directory(HANDLE handle, uint
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    
                         /* JIF  
                            printf("Stat: %s\n", fullpath); */  
1094                          if (stat(fullpath, &fstat))                          if (stat(fullpath, &fstat))
1095                          {                          {
1096                                  perror("stat");                                  switch (errno)
1097                                  out_uint8(out, 0);                                  {
1098                                  return STATUS_ACCESS_DENIED;                                          case ENOENT:
1099                                            case ELOOP:
1100                                            case EACCES:
1101                                                    /* These are non-fatal errors. */
1102                                                    memset(&fstat, 0, sizeof(fstat));
1103                                                    break;
1104                                            default:
1105                                                    /* Fatal error. By returning STATUS_NO_SUCH_FILE,
1106                                                       the directory list operation will be aborted */
1107                                                    perror(fullpath);
1108                                                    out_uint8(out, 0);
1109                                                    return STATUS_NO_SUCH_FILE;
1110                                    }
1111                          }                          }
1112    
1113                          if (S_ISDIR(fstat.st_mode))                          if (S_ISDIR(fstat.st_mode))
# Line 888  disk_query_directory(HANDLE handle, uint Line 1151  disk_query_directory(HANDLE handle, uint
1151                          break;                          break;
1152    
1153                  default:                  default:
1154                            /* FIXME: Support FileDirectoryInformation,
1155                               FileFullDirectoryInformation, and
1156                               FileNamesInformation */
1157    
1158                          unimpl("IRP Query Directory sub: 0x%x\n", info_class);                          unimpl("IRP Query Directory sub: 0x%x\n", info_class);
1159                          return STATUS_INVALID_PARAMETER;                          return STATUS_INVALID_PARAMETER;
# Line 899  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    

Legend:
Removed from v.686  
changed lines
  Added in v.827

  ViewVC Help
Powered by ViewVC 1.1.26