Initial repo
[fsviewer.git] / src / files.c
blobdde06a42155154fbedccd9b88c74dc3e3f358c77
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include <unistd.h>
7 #include <sys/types.h>
8 #include <sys/wait.h>
9 #include <sys/stat.h>
10 #include <fcntl.h>
11 #include <errno.h>
12 #include <dirent.h>
13 #include <stdarg.h>
14 #include <WINGs/WINGs.h>
15 #include <WINGs/WUtil.h>
17 #include "FSViewer.h"
18 #include "FSUtils.h"
19 #include "misc.h"
21 static Bool DISPLAY_HIDDEN_FILES = False;
22 static Bool SORT_TOGGLE = True;
24 static int copy(ino_t *inodes, int n_inodes, char *oldpath, char *newpath);
25 static int copyfile(char *oldpath, char *newpath);
26 static int copydir(ino_t *inodes, int n_inodes, struct stat *oldstats,
27 char *oldpath, char *newpath);
30 ** Here's an example of how to sort a singly-linked list. I think it
31 ** can be modified to sort a doubly-linked list, but it would get a bit
32 ** more complicated. Note that this is a recursive method, but the
33 ** recursion depth is limited to be proportional to the base 2 log of
34 ** the length of the list, so it won't "run away" and blow the stack.
36 ** 10/21/93 rdg Fixed bug -- function was okay, but called incorrectly.
37 ** linked list sort -- public domain by Ray Gardner 5/90
40 /*
41 Taken from the code snippet website (sorry no URL)
42 Functions modified on 98/10/14 by George Clernon (clernong@tinet.ie)
43 for Workplace.app list type.
46 /* returns < 0 if *p sorts lower than *q */
47 int keycmp (FileInfo *p, FileInfo *q)
49 if( FSGetIntegerForName("SortOrder") )
50 return strcasecmp(p->name, q->name);
51 else
52 return strcasecmp(q->name, p->name);
55 /* merge 2 lists under dummy head item */
56 FileInfo *lmerge (FileInfo *p, FileInfo *q)
58 FileInfo *r, head;
60 for ( r = &head; p && q; )
62 if ( keycmp(p, q) < 0 )
64 r = r->next = p;
65 p = p->next;
67 else
69 r = r->next = q;
70 q = q->next;
73 r->next = (p ? p : q);
75 return head.next;
78 /* split list into 2 parts, sort each recursively, merge */
79 FileInfo *lsort (FileInfo *p)
81 FileInfo *q, *r;
83 if ( p )
85 q = p;
86 for ( r = q->next; r && (r = r->next) != NULL; r = r->next )
87 q = q->next;
89 r = q->next;
90 q->next = NULL;
92 if ( r )
93 p = lmerge(lsort(r), lsort(p));
95 return p;
98 /* FileInfo *GetDirList(char *path) */
99 /* { */
100 /* char *fullPath; */
101 /* FileInfo *top; */
102 /* FileInfo *fileList; */
103 /* struct dirent *dirent; */
104 /* DIR *dir; */
106 /* fullPath = wexpandpath(path); */
108 /* dir = opendir(fullPath); */
109 /* if (!dir) */
110 /* { */
111 /* printf("Unable to open dir: %s\n", path); */
112 /* return NULL; */
113 /* } */
115 /* fileList = (FileInfo *) wmalloc(sizeof(FileInfo)); */
116 /* fileList->next = NULL; */
117 /* fileList->name = NULL; */
118 /* fileList->fileType = NORMAL; */
119 /* fileList->imgName = NULL; */
120 /* fileList->abbrev = NULL; */
121 /* top = fileList; */
123 /* dirent = readdir(dir); */
124 /* while(dirent) */
125 /* { */
126 /* GetFileInfo(fullPath, dirent->d_name, fileList); */
128 /* dirent = readdir(dir); */
130 /* if(dirent) */
131 /* { */
132 /* fileList->next = (FileInfo *) wmalloc(sizeof(FileInfo)); */
133 /* fileList = fileList->next; */
134 /* fileList->next = NULL; */
135 /* } */
136 /* } */
138 /* closedir(dir); */
140 /* if(fullPath) */
141 /* free(fullPath); */
143 /* return lsort(top); */
144 /* } */
146 FileInfo *GetDirList(char *path)
148 Bool mixed = False;
149 Bool dirFirst = False;
150 char *fullPath = NULL;
151 FileInfo *topDir = NULL;
152 FileInfo *topFile = NULL;
153 FileInfo *dirList = NULL;
154 FileInfo *fileList = NULL;
155 FileInfo *fileInfo = NULL;
156 struct dirent *dirent = NULL;
157 DIR *dir = NULL;
159 fullPath = wexpandpath(path);
161 dir = opendir(fullPath);
162 if (!dir)
164 /* printf("Unable to open dir: %s\n", path); */
165 return NULL;
168 if(FSGetIntegerForName("SortDisplay") == 0)
169 mixed = True;
170 else if(FSGetIntegerForName("SortDisplay") == 2)
171 dirFirst = True;
173 while( (dirent = readdir(dir)) != NULL)
175 fileInfo = FSCreateFileInfo();
177 GetFileInfo(fullPath, dirent->d_name, fileInfo);
179 if( !mixed && isDirectory(fileInfo->fileType) )
181 if(dirList)
183 dirList->next = fileInfo;
184 dirList = dirList->next;
186 else
188 dirList = fileInfo;
189 topDir = dirList;
192 else
194 if(fileList)
196 fileList->next = fileInfo;
197 fileList = fileList->next;
199 else
201 fileList = fileInfo;
202 topFile = fileList;
207 closedir(dir);
209 if(fullPath)
210 free(fullPath);
212 if(topFile)
213 fileList = lsort(topFile);
214 if(topDir)
215 dirList = lsort(topDir);
217 if(dirFirst)
219 if(dirList)
221 topFile = dirList;
222 while(dirList->next != NULL)
223 dirList = dirList->next;
224 dirList->next = fileList;
226 else
227 topFile = fileList;
229 else
231 if(fileList)
233 topFile = fileList;
234 while(fileList->next != NULL)
235 fileList = fileList->next;
236 fileList->next = dirList;
238 else
239 topFile = dirList;
242 return topFile;
245 void GetFileInfo(char* path, char *name, FileInfo* fileInfo)
247 struct stat *st;
248 char *pathname;
249 char *fileName;
250 char *dirPath;
252 st = (struct stat *) wmalloc(sizeof(struct stat));
254 /* make abosolute pathname */
255 pathname = (char *) wmalloc(strlen(path)+strlen(name)+1);
256 strcpy(pathname, path);
257 pathname = strcat(pathname, name);
259 /* get information of a file represented by pathname */
260 if (stat(pathname, st) == -1)
261 wwarning(_("%s GetFileInfo %d: Stat Error for %s\n"),
262 __FILE__, __LINE__, pathname);
264 if(strcmp("/", pathname) == 0)
266 fileInfo->fileType = ROOT;
267 fileName = FSNodeName();
269 else if(strcmp(FSGetHomeDir(), pathname) == 0) {
270 fileInfo->fileType = HOME;
271 fileName = (char *) wmalloc(strlen(name)+1);
272 strcpy(fileName, name);
274 else
276 if(S_ISDIR(st->st_mode))
277 fileInfo->fileType = DIRECTORY;
278 else
279 fileInfo->fileType = NORMAL;
281 fileName = (char *) wmalloc(strlen(name)+1);
282 strcpy(fileName, name);
285 dirPath = (char *) wmalloc(strlen(path)+1);
286 strcpy(dirPath, path);
288 fileInfo->name = fileName;
289 fileInfo->path = dirPath;
291 if(fileInfo->fileType == ROOT)
292 fileInfo->extn = wstrdup("ROOT");
293 else
294 fileInfo->extn = wstrdup(GetFileExtn(fileInfo->name));
296 fileInfo->imgName = GetFileImgName(GetFileExtn(fileName),
297 fileInfo->fileType);
298 fileInfo->abbrev = GetFileAbbrev(fileName);
301 fileInfo->st = st;
303 /* if (st) */
304 /* { */
305 /* free(st); */
306 /* st = NULL; */
307 /* } */
309 if(pathname)
311 free(pathname);
312 pathname = NULL;
317 char*
318 RemoveFileExtension(char* filename)
320 char *tmp;
321 char *str;
322 int len;
324 tmp = strrchr(filename, '.');
326 len = strlen(filename)-strlen(tmp);
328 str = (char *) wmalloc(len+1);
329 strncpy(str, filename, len);
330 str[len] = '\0';
332 return str;
335 char *
336 GetFileExtn(char *filename)
338 char *extn;
340 if(FSStringMatch("*.tar.gz", filename))
341 return wstrdup(".tar.gz");
343 extn = strrchr(filename, '.');
345 if(extn == NULL)
347 /* extn = (char *) wmalloc(strlen(filename)+1); */
348 /* strcpy(extn, filename); */
349 extn = wstrdup(filename);
352 return extn;
356 char *GetFileAbbrev(char *fileName)
358 char *abbrev;
359 /* int i; */
361 abbrev = (char *) wmalloc(strlen(fileName)+1);
363 if (strlen(fileName)>19)
365 strncpy(abbrev, fileName, 16);
366 abbrev[16] = '\0';
367 strcat(abbrev, "...");
370 else
372 strcpy(abbrev, fileName);
375 return abbrev;
378 char* GetFileImgName(char *fileName, enum FileType fileType)
380 /*WMPropList* dict, value = NULL;*/
381 char *extn = NULL;
382 char *icon = NULL;
383 char *name = NULL;
386 * I'm not sure what should happen here
387 * Cos the event should really arise.
388 * Need to improve error handling in functions
389 * that call this one
391 if(fileName == NULL)
392 return wstrdup(DEFAULT_STR);
395 if(fileType == ROOT)
396 extn = wstrdup("ROOT");
397 else
398 extn = wstrdup(GetFileExtn(fileName));
400 name = FSGetStringForNameKey(extn, "icon");
402 if(name == NULL)
404 if(fileType == DIRECTORY)
405 name = FSGetStringForName(DIR_STR);
406 else if(fileType == ROOT)
407 name = FSGetStringForNameKey(ROOT_STR, "icon");
408 else if(fileType == HOME)
409 name = FSGetStringForName(HOME_STR);
410 else
411 name = FSGetStringForName(DEFAULT_STR);
414 icon = LocateImage(name);
415 if(name)
416 free(name);
417 if(extn)
418 free(extn);
420 if(icon)
421 return icon;
422 else
423 return wstrdup(DEFAULT_STR);
425 /* dict = PLGetDictionaryEntry(filesDB, PLMakeString(extn)); */
426 /* if(dict && PLIsDictionary(dict)) */
427 /* { */
428 /* value = PLGetDictionaryEntry(dict, PLMakeString("icon")); */
429 /* } */
431 /* if(value == NULL) */
432 /* { */
433 /* if(fileType == DIRECTORY) */
434 /* value = PLGetDictionaryEntry(filesDB, PLMakeString(DIR_STR)); */
435 /* else if(fileType == ROOT) */
436 /* value = PLGetDictionaryEntry(filesDB, PLMakeString(ROOT_STR)); */
437 /* else if(fileType == HOME) */
438 /* value = PLGetDictionaryEntry(filesDB, PLMakeString(HOME_STR)); */
439 /* else */
440 /* { */
441 /* value = PLGetDictionaryEntry(filesDB, PLMakeString(DEFAULT_STR)); */
442 /* } */
443 /* } */
445 /* if(extn) */
446 /* free(extn); */
448 /* No Icons at all!! */
449 /* if(value == NULL) */
450 /* { */
451 /* return DEFAULT_STR; */
452 /* } */
454 /* return PLGetString(value); */
458 char*
459 GetNameFromPathname(char* pathname)
461 char *str;
463 str = strrchr(pathname, '/');
464 str++;
466 return wstrdup(str);
469 char* GetPathFromPathname(char* pathname)
471 int lenTot;
472 int lenName;
473 int lenPath;
474 char *path;
476 lenTot = strlen(pathname);
477 lenName = strlen(GetNameFromPathname(pathname));
478 lenPath = lenTot - lenName;
480 path = (char *) wmalloc(lenPath+1);
481 strncpy(path, pathname, lenPath);
482 path[lenPath] = '\0';
484 return path;
487 char* GetPathnameFromPathName(char* path, char *name)
489 int len;
490 char *pathname;
492 len = strlen(GetNameFromPathname(path));
493 if(len)
495 pathname = (char *)wmalloc(strlen(path)+strlen(name)+2);
496 strcpy(pathname, path);
497 strcat(pathname, "/");
498 strcat(pathname, name);
500 else
502 pathname = (char *)wmalloc(strlen(path)+strlen(name)+1);
503 strcpy(pathname, path);
504 strcat(pathname, name);
507 return pathname;
510 Bool isDirectory(enum FileType fileType)
513 if(fileType == DIRECTORY || fileType == ROOT || fileType == HOME)
514 return True;
516 return False;
519 Bool
520 DisplayFile(char *str, char *filter, FileType fileType)
523 /* if(str[0] != '.') */
524 /* { */
525 /* return True; */
526 /* } */
527 /* else if(DISPLAY_HIDDEN_FILES) */
528 /* { */
529 /* if(str[1] != '.' && str[1] != '\0') */
530 /* return True; */
531 /* } */
533 /* return False; */
536 if( !strcmp(".", str) || !strcmp("..", str) )
537 return False;
538 else if( filter && !isDirectory(fileType) )
539 if( !FSStringMatch(filter, str) )
540 return False;
542 if( str[0] == '.' )
543 return FSGetIntegerForName("DisplayDotFiles");/* DISPLAY_HIDDEN_FILES; */
545 return True;
548 void
549 FSToggleDisplayHiddenFiles()
551 /* DISPLAY_HIDDEN_FILES = !DISPLAY_HIDDEN_FILES; */
552 /* if( FSGetIntegerForName("DisplayDotFiles") )
553 FSSetIntegerForName("DisplayDotFiles", 0);
554 else
555 FSSetIntegerForName("DisplayDotFiles", 1);*/
556 FSSetIntegerForName("DisplayDotFiles",
557 !FSGetIntegerForName("DisplayDotFiles"));
560 void
561 FSToggleSort()
563 /* SORT_TOGGLE = !SORT_TOGGLE; */
564 /* if( FSGetIntegerForName("SortOrder") )
565 FSSetIntegerForName("SortOrder", 0);
566 else
567 FSSetIntegerForName("SortOrder", 1);*/
568 FSSetIntegerForName("SortOrder",
569 !FSGetIntegerForName("SortOrder"));
572 FileInfo *
573 FSCreateFileInfo()
576 FileInfo *fileInfo;
578 fileInfo = (FileInfo *) wmalloc(sizeof(FileInfo));
579 memset(fileInfo, 0, sizeof(FileInfo));
580 /* fileInfo->next = NULL; */
581 /* fileInfo->name = NULL; */
582 /* fileInfo->path = NULL; */
583 fileInfo->fileType = NORMAL;
584 fileInfo->imgName = GetFileImgName(NULL_STR, NORMAL);
585 /* fileInfo->abbrev = NULL; */
586 /* fileInfo->extn = NULL; */
587 /* fileInfo->st = NULL; */
589 return fileInfo;
594 void
595 FSCopyFileInfo(FileInfo *src, FileInfo *dest)
598 if(src == NULL || dest == NULL)
599 return;
601 if(src->name)
603 dest->name = (char *) wrealloc(dest->name, strlen(src->name)+1);
604 strcpy(dest->name, src->name);
606 else
607 dest->name = NULL;
609 if(src->path)
611 dest->path =(char *) wrealloc(dest->path, strlen(src->path)+1);
612 strcpy(dest->path, src->path);
614 else
615 dest->path = NULL;
617 if(src->extn)
619 dest->extn = (char *) wrealloc(dest->extn, strlen(src->extn)+1);
620 strcpy(dest->extn, src->extn);
622 else
623 dest->extn = NULL;
625 if(src->abbrev)
627 dest->abbrev = (char *) wrealloc(dest->abbrev, strlen(src->abbrev)+1);
628 strcpy(dest->abbrev, src->abbrev);
630 else
631 dest->abbrev = NULL;
633 if(src->imgName)
635 dest->imgName = (char*)wrealloc(dest->imgName, strlen(src->imgName)+1);
636 strcpy(dest->imgName, src->imgName);
638 else
639 dest->imgName = NULL;
641 dest->fileType = src->fileType;
644 * Not sure if I really want to do this!!!
645 * It should be done though, I think I'll call back later
647 /* if(src->next) */
648 /* { */
649 /* dest->next = FSCreateFileInfo(); */
650 /* FSCopyFileInfo(src->next, dest->next); */
651 /* } */
655 void
656 FSFreeFileInfo(FileInfo *fileInfo)
658 if(!fileInfo)
659 return;
661 if(fileInfo->name)
663 free(fileInfo->name);
664 fileInfo->name = NULL;
666 if(fileInfo->path)
668 free(fileInfo->path);
669 fileInfo->path = NULL;
671 if(fileInfo->imgName)
673 free(fileInfo->imgName);
674 fileInfo->imgName = NULL;
676 if(fileInfo->extn)
678 free(fileInfo->extn);
679 fileInfo->extn = NULL;
681 if(fileInfo->abbrev)
683 free(fileInfo->abbrev);
684 fileInfo->abbrev = NULL;
686 if (fileInfo->st)
688 free(fileInfo->st);
689 fileInfo->st = NULL;
692 if(fileInfo->next)
693 FSFreeFileInfo(fileInfo->next);
695 free(fileInfo);
696 fileInfo = NULL;
699 /* check whether a file exists */
700 int
701 FSFileExists(char *path)
703 struct stat stats;
705 return (!lstat(path, &stats));
708 FileInfo *
709 FSGetFileInfo(char* pathname)
711 char *path;
712 char *name;
713 FileInfo *fileInfo = FSCreateFileInfo();
715 name = GetNameFromPathname(pathname);
716 path = GetPathFromPathname(pathname);
718 GetFileInfo(path, name, fileInfo);
720 return fileInfo;
723 /* create a new directory */
724 int
725 FSCreateNewFile(char *path, mode_t mode)
727 int file = open(path, O_WRONLY|O_CREAT|O_EXCL, mode);
729 if (file == -1 || close(file))
730 return -1;
731 else
732 return 0;
735 /* create a new file */
736 int
737 FSCreateNewDirectory(char *path, mode_t mode)
739 return mkdir(path, mode);
741 /* if (mkdir(path, mode)) */
742 /* { */
743 /* char s[0xff]; */
745 /* sprintf(s, "Error creating folder %s:", path); */
746 /* FSErrorDialog("File Operation Error", s); */
747 /* } */
750 /*-------------------------------------------------------------------------*/
752 /* recursive copy operation */
754 int
755 FSRCopy(char *oldpath, char *newpath)
757 return copy((ino_t *)NULL, 0, oldpath, newpath);
760 static int
761 copyfile(char *oldpath, char *newpath)
763 struct stat stats;
764 int src = -1, dest = -1, n, errno_ret;
765 char buf[BUFSIZ];
767 if ((src = open(oldpath, O_RDONLY)) == -1 || stat(oldpath, &stats))
768 goto err;
769 else if ((dest = creat(newpath, stats.st_mode)) == -1)
770 goto err;
772 while ( (n = read(src, buf, BUFSIZ)) != 0)
773 if ( n == -1 || write(dest, buf, n) != n )
774 goto err;
776 if (close(src))
778 src = -1;
779 goto err;
781 else
782 return close(dest);
784 err:
785 errno_ret = errno;
786 if (src != -1) close(src);
787 if (dest != -1) close(dest);
788 errno = errno_ret;
789 return -1;
792 static int
793 copydir(ino_t *inodes, int n_inodes, struct stat *oldstats,
794 char *oldpath, char *newpath)
796 DIR *dir;
797 struct dirent *entry;
798 int i, ol = strlen(oldpath), nl = strlen(newpath);
799 struct stat newstats;
800 mode_t umask = FSGetUMask();
802 for (i = n_inodes-1; i >= 0; i--)
803 if (inodes[i] == oldstats->st_ino)
805 errno = EINVAL;
806 return -1;
809 if ((mkdir(newpath, umask & 0777) < 0 && errno != EEXIST) ||
810 lstat(newpath, &newstats) ||
811 !(dir = opendir(oldpath)))
812 return -1;
814 inodes = (ino_t *) wrealloc(inodes, (n_inodes+1)*sizeof(ino_t));
815 inodes[n_inodes++] = newstats.st_ino;
817 for(i = 0; (entry = readdir(dir)); i++)
818 if (entry->d_name[0] != '.' || (entry->d_name[1] != '\0'
819 && (entry->d_name[1] != '.' ||
820 entry->d_name[2] != '\0')))
822 int ol1 = ol, nl1 = nl, l = strlen(entry->d_name);
823 char *oldpath1 = (char *)alloca(ol1+l+2);
824 char *newpath1 = (char *)alloca(nl1+l+2);
826 strcpy(oldpath1, oldpath);
827 strcpy(newpath1, newpath);
828 if (oldpath1[ol1-1] != '/')
829 oldpath1[ol1++] = '/';
830 if (newpath1[nl1-1] != '/')
831 newpath1[nl1++] = '/';
832 strcpy(oldpath1+ol1, entry->d_name);
833 strcpy(newpath1+nl1, entry->d_name);
834 if (copy(inodes, n_inodes, oldpath1, newpath1))
836 /* take care of recursive errors */
837 char s[0xff];
838 sprintf(s, _("Error copying %s:"), oldpath1);
839 FSErrorDialog(_("File Operation Error"), s);
843 inodes = (ino_t *) wrealloc(inodes, (n_inodes-1)*sizeof(ino_t));
844 return closedir(dir);
847 static int
848 copy(ino_t *inodes, int n_inodes, char *oldpath, char *newpath)
850 struct stat stats;
851 mode_t umask = FSGetUMask();
853 if (lstat(oldpath, &stats))
854 return -1;
856 /* Directory: copy recursively */
857 if (S_ISDIR(stats.st_mode))
858 return copydir(inodes, n_inodes, &stats, oldpath, newpath);
860 /* Regular file: copy block by block */
861 else if (S_ISREG(stats.st_mode))
862 return copyfile(oldpath, newpath);
864 /* Fifo: make a new one */
865 else if (S_ISFIFO(stats.st_mode))
866 return mkfifo(newpath, umask & 0666);
868 /* Device: make a new one */
869 else if (S_ISBLK(stats.st_mode) || S_ISCHR(stats.st_mode) ||
870 S_ISSOCK(stats.st_mode))
871 return mknod(newpath, umask & 0666, stats.st_rdev);
873 /* Symbolic link: make a new one */
874 else if (S_ISLNK(stats.st_mode))
876 char lnk[MAX_LEN+1];
877 int l = readlink(oldpath, lnk, MAX_LEN);
879 if (l<0)
880 return -1;
881 lnk[l] = '\0';
882 return(symlink(lnk, newpath));
885 /* This shouldn't happen */
886 else
888 char s[0xff];
889 sprintf(s, _("Unrecognized File type: %s"), oldpath);
890 FSErrorDialog(_("File Operation Error"), s);
892 return 0;
896 /*-------------------------------------------------------------------------*/
898 /* recursive delete */
900 int
901 FSRDel(char *path)
903 struct stat stats;
905 if (lstat(path, &stats))
906 return -1;
908 if (S_ISDIR(stats.st_mode))
910 DIR *dir;
911 struct dirent *entry;
912 int i, pl = strlen(path);
914 if (!(dir = opendir(path)))
915 return -1;
917 for(i = 0; (entry = readdir(dir)); i++)
918 if (entry->d_name[0] != '.' || (entry->d_name[1] != '\0'
919 && (entry->d_name[1] != '.' ||
920 entry->d_name[2] != '\0')))
922 int pl1 = pl, l = strlen(entry->d_name);
923 char *path1 = (char *)alloca(pl1+l+2);
925 strcpy(path1, path);
926 if (path1[pl1-1] != '/')
927 path1[pl1++] = '/';
928 strcpy(path1+pl1, entry->d_name);
929 if (FSRDel(path1)) {
930 /* take care of recursive errors */
931 char s[0xff];
932 sprintf(s, _("Error deleting %s:"), path);
933 FSErrorDialog(_("File Operation Error"), s);
937 if (closedir(dir))
938 return -1;
939 else
940 return rmdir(path);
942 else
943 return unlink(path);
946 void
947 FSCopy(FileInfo *src, FileInfo *dest)
949 struct stat stats;
950 int i, toi, n_copied = 0;
951 char *from = NULL;
952 char to[MAX_LEN];
954 from = GetPathnameFromPathName(src->path, src->name);
955 strcpy(to, GetPathnameFromPathName(dest->path, dest->name));
957 if (access(to, W_OK) && isDirectory(dest->fileType))
959 char s[0xff];
961 sprintf(s, _("No write access to %s"), to);
962 FSErrorDialog(_("File Operation Error"), s);
963 if(from)
964 free(from);
965 return;
969 if target exists and is a directory, copy the source
970 into that directory
972 if(!stat(to, &stats) && S_ISDIR(stats.st_mode))
974 if (!strcmp(from, to))
976 FSErrorDialog(_("File Operation Error"),
977 _("Copy: Source and destination are identical"));
978 if(from)
979 free(from);
980 return;
983 toi = strlen(to);
984 if(to[toi-1] != '/')
986 to[toi++] = '/';
987 to[toi] = '\0';
991 Should do a loop here that goes through each element
992 of the FileInfo list, checks and copies it
994 strcpy(to+toi, src->name);
995 if(FSFileExists(to) /* && resources.confirm_overwrite */)
997 char s[0xff];
998 sprintf(s, _("Copy: file %s already exists at destination"),
999 src->name);
1000 if(FSConfirmationDialog(_("Overwrite?"), s))
1002 if(from)
1003 free(from);
1004 return;
1008 if(FSRCopy(from, to))
1010 char s[0xff];
1011 sprintf(s, _("Error copying %s:"), from);
1012 FSErrorDialog(_("File Operation Error"), s);
1014 else
1015 n_copied++;
1019 otherwise only a single file may be selected;
1020 copy it to the target file
1022 /* else if (popups.fw->n_selections > 1) */
1023 /* { */
1024 /* error("Copy: target for multiple files", "must be a folder"); */
1025 /* goto out; */
1026 /* } */
1027 else
1029 struct stat stats1;
1031 if(!stat(from, &stats1) && S_ISDIR(stats1.st_mode))
1033 FSErrorDialog(_("File Operation Error"),
1034 _("Cannot copy a directory to a file"));
1035 if(from)
1036 free(from);
1037 return;
1040 if (!lstat(to, &stats) && !lstat(from, &stats1) &&
1041 stats.st_ino == stats1.st_ino)
1043 FSErrorDialog(_("File Operation Error"),
1044 _("Copy: Source and destination are identical"));
1045 if(from)
1046 free(from);
1047 return;
1050 if (FSFileExists(to) /* && resources.confirm_overwrite */)
1052 char s[0xff];
1053 sprintf(s, _("Copy: file %s already exists"), to);
1054 if(FSConfirmationDialog(_("Overwrite?"), s))
1056 if(from)
1057 free(from);
1058 return;
1062 if (FSRCopy(from, to))
1064 char s[0xff];
1065 sprintf(s, _("Error copying %s:"), from);
1066 FSErrorDialog(_("File Operation Error"), s);
1068 else
1069 n_copied = 1;
1072 if (n_copied)
1073 FSUpdateFileView(FileCopy, src, dest);
1075 if(from)
1076 free(from);
1079 void
1080 FSDelete(FileInfo *item)
1082 char s[0xff];
1083 char *itemName;
1084 int i, n_deleted = 0;
1086 itemName = GetPathnameFromPathName(item->path, item->name);
1088 if (isDirectory(item->fileType))
1089 if (!strcmp(item->name, ".") || !strcmp(item->name, ".."))
1091 FSErrorDialog(_("File Operation Error"), _("Cannot delete . or .."));
1092 if(itemName)
1093 free(itemName);
1094 return;
1096 /* else if (resources.confirm_delete_folder) */
1097 /* { */
1099 /* sprintf(s, "Do you REALLY wish to delete folder %s"\ */
1100 /* "and ALL items contained in it?", itemName); */
1102 sprintf(s, _("Do you REALLY wish to delete %s"), itemName);
1104 if(FSConfirmationDialog(_("File Operation"), s))
1106 if(itemName)
1107 free(itemName);
1108 return;
1110 /* } */
1112 if (FSRDel(itemName))
1114 sprintf(s, _("Error deleting %s:"), itemName);
1115 FSErrorDialog(_("File Operation Error"), s);
1117 else
1118 n_deleted++;
1120 if(n_deleted)
1121 FSUpdateFileView(FileDelete, item, NULL);
1123 if(itemName)
1124 free(itemName);
1127 void
1128 FSMove(FileInfo *src, FileInfo *dest)
1130 struct stat stats;
1131 int i, toi, n_moved = 0;
1132 char *from = NULL;
1133 char to[MAX_LEN];
1135 from = GetPathnameFromPathName(src->path, src->name);
1136 strcpy(to, GetPathnameFromPathName(dest->path, dest->name));
1138 if(access(to, W_OK) && isDirectory(dest->fileType))
1140 char s[0xff];
1142 sprintf(s, _("No write access to %s"), to);
1143 FSErrorDialog(_("File Operation Error"), s);
1144 if(from)
1145 free(from);
1146 return;
1150 if target exists and is a directory, move the source
1151 into that directory
1153 if(!stat(to, &stats) && S_ISDIR(stats.st_mode))
1155 if (!strcmp(from, to))
1157 FSErrorDialog(_("File Operation Error"),
1158 _("Move: Source and destination are identical"));
1159 if(from)
1160 free(from);
1161 return;
1164 toi = strlen(to);
1165 if(to[toi-1] != '/')
1167 to[toi++] = '/';
1168 to[toi] = '\0';
1172 Should do a loop here that goes through each element
1173 of the FileInfo list, checks and moves it
1175 strcpy(to+toi, src->name);
1176 if(FSFileExists(to) /* && resources.confirm_overwrite */)
1178 char s[0xff];
1179 sprintf(s, _("Move: file %s already exists at destination"),
1180 src->name);
1181 if(FSConfirmationDialog(_("Overwrite?"), s))
1183 if(from)
1184 free(from);
1186 return;
1189 if(rename(from, to))
1191 char s[0xff];
1192 sprintf(s, _("Error copying %s:"), from);
1193 FSErrorDialog(_("File Operation Error"), s);
1194 if(from)
1195 free(from);
1197 else
1198 n_moved++;
1201 otherwise only a single file may be selected;
1202 copy it to the target file
1204 /* else if (popups.fw->n_selections > 1) */
1205 /* { */
1206 /* error("Copy: target for multiple files", "must be a folder"); */
1207 /* goto out; */
1208 /* } */
1209 else
1211 struct stat stats1;
1213 if(!stat(from, &stats1) && S_ISDIR(stats1.st_mode))
1215 FSErrorDialog(_("File Operation Error"),
1216 _("Cannot move a directory to a file"));
1217 if(from)
1218 free(from);
1219 return;
1222 if (!lstat(to, &stats) && !lstat(from, &stats1) &&
1223 stats.st_ino == stats1.st_ino)
1225 FSErrorDialog(_("File Operation Error"),
1226 _("Move: Source and destination are identical"));
1227 if(from)
1228 free(from);
1229 return;
1232 if (FSFileExists(to) /* && resources.confirm_overwrite */)
1234 char s[0xff];
1235 sprintf(s, _("Move: file %s already exists"), to);
1236 if(FSConfirmationDialog(_("Overwrite?"), s))
1238 if(from)
1239 free(from);
1240 return;
1244 if (rename(from, to))
1246 char s[0xff];
1247 sprintf(s, _("Error renaming %s:"), from);
1248 FSErrorDialog(_("File Operation Error"), s);
1250 else
1251 n_moved = 1;
1254 if (n_moved)
1255 FSUpdateFileView(FileMove, src, dest);
1257 if(from)
1258 free(from);
1261 void
1262 FSRename(FileInfo *src, FileInfo *dest)
1264 struct stat stats;
1265 struct stat stats1;
1266 int i, toi, n_renamed = 0;
1267 char *from = NULL;
1268 char *to = NULL;
1270 from = GetPathnameFromPathName(src->path, src->name);
1271 to = GetPathnameFromPathName(dest->path, dest->name);
1274 if (!lstat(to, &stats) && !lstat(from, &stats1) &&
1275 stats.st_ino == stats1.st_ino)
1277 FSErrorDialog(_("File Operation Error"),
1278 _("Rename: Source and destination are identical"));
1279 if(from)
1280 free(from);
1281 if(to)
1282 free(to);
1283 return;
1286 if (FSFileExists(to) /* && resources.confirm_overwrite */)
1288 char s[0xff];
1289 sprintf(s, _("Rename: file %s already exists"), to);
1290 if(FSConfirmationDialog(_("Overwrite?"), s))
1292 if(from)
1293 free(from);
1294 if(to)
1295 free(to);
1296 return;
1300 if (rename(from, to))
1302 char s[0xff];
1303 sprintf(s, _("Error renaming %s:"), from);
1304 FSErrorDialog(_("File Operation Error"), s);
1306 else
1307 n_renamed = 1;
1309 if (n_renamed)
1310 FSUpdateFileView(FileRename, src, dest);
1312 if(from)
1313 free(from);
1314 if(to)
1315 free(to);
1318 void
1319 FSLink(FileInfo *src, FileInfo *dest)
1321 struct stat stats;
1322 int i, toi, n_linked = 0;
1323 char *from = NULL;
1324 char *to = NULL;
1326 from = GetPathnameFromPathName(src->path, src->name);
1327 to = GetPathnameFromPathName(dest->path, dest->name);
1330 if target exists and is a directory,
1331 link the source into that directory
1333 if(!stat(to, &stats) && S_ISDIR(stats.st_mode))
1335 if (!strcmp(from, to))
1337 FSErrorDialog(_("File Operation Error"),
1338 _("Copy: Source and destination are identical"));
1339 if(from)
1340 free(from);
1341 if(to)
1342 free(to);
1343 return;
1346 toi = strlen(to);
1347 if(to[toi-1] != '/')
1349 to[toi++] = '/';
1350 to[toi] = '\0';
1354 Should do a loop here that goes through each element
1355 of the FileInfo list, checks and copies it
1357 strcpy(to+toi, src->name);
1358 if(FSFileExists(to) /* && resources.confirm_overwrite */)
1360 char s[0xff];
1361 sprintf(s, _("Link: file %s already exists at destination"),
1362 src->name);
1363 if(FSConfirmationDialog(_("Overwrite?"), s))
1365 if(from)
1366 free(from);
1367 if(to)
1368 free(to);
1369 return;
1373 if (symlink(from,to))
1375 char s[0xff];
1376 sprintf(s, _("Error linking %s to %s"), from, to);
1377 FSErrorDialog(_("File Operation Error"), s);
1379 else
1380 n_linked++;
1382 /* otherwise only a single file may be selected;
1383 link it to the target file */
1384 /* else if (popups.fw->n_selections > 1) { */
1386 /* error("Link: target for multiple files", "must be a folder"); */
1387 /* goto out; */
1389 /* } */
1390 else
1392 struct stat stats1;
1394 if (!lstat(to, &stats) && !lstat(from, &stats1) &&
1395 stats.st_ino == stats1.st_ino)
1397 FSErrorDialog(_("File Operation Error"),
1398 _("Link: Source and destination are identical"));
1399 if(from)
1400 free(from);
1401 if(to)
1402 free(to);
1403 return;
1406 if (FSFileExists(to) /* && resources.confirm_overwrite */)
1408 char s[0xff];
1409 sprintf(s, _("Link: file %s already exists"), to);
1410 if(FSConfirmationDialog(_("Overwrite?"), s))
1412 if(from)
1413 free(from);
1414 if(to)
1415 free(to);
1416 return;
1420 if(symlink(from,to))
1422 char s[0xff];
1423 sprintf(s, _("Error linking %s to %s"), from, to);
1424 FSErrorDialog(_("File Operation Error"), s);
1426 else
1427 n_linked = 1;
1430 if (n_linked)
1431 FSUpdateFileView(FileLink, src, dest);
1433 if(from)
1434 free(from);
1435 if(to)
1436 free(to);