2 * [un]trash command for Haiku
3 * Copyright (c) 2004, Francois Revol - revol@free.fr
4 * provided under the MIT licence
10 #include <app/Message.h>
11 #include <app/Messenger.h>
12 #include <kernel/fs_attr.h>
13 #include <kernel/fs_info.h>
14 #include <storage/Directory.h>
15 #include <storage/Entry.h>
16 #include <storage/FindDirectory.h>
17 #include <storage/Node.h>
18 #include <storage/Path.h>
19 #include <support/TypeConstants.h>
21 static const char *kAttrOriginalPath
= "_trk/original_path";
22 static const char *kTrackerSig
= "application/x-vnd.Be-TRAK";
26 printf("\nSend files to trash, or restore them.\nUsage:\n");
27 printf("trash [--restore|--empty|--list] file ...\n");
28 printf("\t--restore\trestore files (act as untrash)\n");
29 printf("\t--empty\t\tempty the Trash\n");
30 printf("\t--list\t\tlist what's already in the Trash\n");
31 printf("untrash [--all] [file ...]\n");
32 //printf("restore [--all] [file ...]\n");
36 status_t
untrash(const char *f
)
39 char original_path
[B_PATH_NAME_LENGTH
];
42 err
= node
.InitCheck();
45 err
= node
.ReadAttr(kAttrOriginalPath
, B_STRING_TYPE
, 0LL, original_path
, B_PATH_NAME_LENGTH
);
48 err
= rename(path
.Path(), original_path
);
51 node
.RemoveAttr(kAttrOriginalPath
);
55 status_t
trash(const char *f
)
61 const char *original_path
;
62 char trash_dir
[B_PATH_NAME_LENGTH
];
63 char trashed_file
[B_PATH_NAME_LENGTH
];
64 dev
= dev_for_path(f
);
65 err
= find_directory(B_TRASH_DIRECTORY
, dev
, false, trash_dir
, B_PATH_NAME_LENGTH
);
69 err
= node
.InitCheck();
72 err
= node
.GetAttrInfo(kAttrOriginalPath
, &ai
);
75 if (!strncmp(f
, trash_dir
, strlen(trash_dir
)))
78 err
= get_ref_for_path(f
, &er
);
80 err
= orgPath
.InitCheck();
83 original_path
= orgPath
.Path();
84 BDirectory
trashDir(trash_dir
);
85 err
= trashDir
.InitCheck();
88 for (nr
= 0; ; nr
++) {
92 snprintf(trashed_file
, B_PATH_NAME_LENGTH
-1, "%s/%s %d", trash_dir
, er
.name
, nr
);
94 snprintf(trashed_file
, B_PATH_NAME_LENGTH
-1, "%s/%s", trash_dir
, er
.name
);
95 if (!trashDir
.Contains(trashed_file
))
98 err
= rename(original_path
, trashed_file
);
102 err
= node
.WriteAttr(kAttrOriginalPath
, B_STRING_TYPE
, 0LL, original_path
, strlen(original_path
)+1);
108 status_t
show_trashed_file(const char *f
)
111 char original_path
[B_PATH_NAME_LENGTH
];
114 err
= node
.ReadAttr(kAttrOriginalPath
, B_STRING_TYPE
, 0LL, original_path
, B_PATH_NAME_LENGTH
);
117 //printf("%s\n\t[from] %s\n", f, original_path);
118 printf("%s\n\tas: %s\n", original_path
, f
);
122 status_t
foreach_in_trash(status_t (*iterator
)(const char *))
126 char trash_dir
[B_PATH_NAME_LENGTH
];
128 if (next_dev(&dev
) < B_OK
)
130 //for each in trash_dir
131 err
= find_directory(B_TRASH_DIRECTORY
, dev
, false, trash_dir
, B_PATH_NAME_LENGTH
);
133 continue; /* skip trashless volumes */
134 BDirectory
trashDir(trash_dir
);
135 err
= trashDir
.InitCheck();
139 while (trashDir
.GetNextRef(&er
) == B_OK
) {
141 if ((err
= path
.InitCheck()))
143 err
= iterator(path
.Path());
152 int main(int argc
, char **argv
)
157 if (strstr(argv
[0], "untrash") || strstr(argv
[0], "restore"))
161 if (!strcmp(argv
[1], "--help"))
163 if (!strcmp(argv
[1], "--restore")) {
167 if (!dountrash
&& !strcmp(argv
[1], "--empty")) {
168 /* XXX: clean that */
169 BMessage
msg(B_DELETE_PROPERTY
);
170 msg
.AddSpecifier("Trash");
171 BMessenger
msgr(kTrackerSig
);
172 err
= msgr
.SendMessage(&msg
);
174 fprintf(stderr
, "Emptying Trash: %s\n", strerror(err
));
179 if (dountrash
&& !strcmp(argv
[i
], "--all")) {
180 /* restore all trashed files */
181 err
= foreach_in_trash(untrash
);
183 fprintf(stderr
, "untrash: %s\n", strerror(err
));
188 if (!strcmp(argv
[i
], "--list")) {
189 err
= foreach_in_trash(show_trashed_file
);
192 /* restore files... */
194 for (; i
< argc
; i
++) {
195 err
= untrash(argv
[i
]);
197 fprintf(stderr
, "%s: %s\n", argv
[i
], strerror(err
));
204 for (i
= 1; i
< argc
; i
++) {
205 err
= trash(argv
[i
]);
207 fprintf(stderr
, "%s: %s\n", argv
[i
], strerror(err
));