vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / tracker / openterminal / OpenTerminal.cpp
bloba43cdb11a175e32658411297c9ba591df15a6f08
1 /*
2 * Copyright 2007 - 2009 Chris Roberts. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Chris Roberts, cpr420@gmail.com
7 */
9 #include <StorageKit.h>
10 #include <SupportKit.h>
11 #include <AppKit.h>
13 #include <vector>
15 #include <add-ons/tracker/TrackerAddOn.h>
17 const char* kTerminalSignature = "application/x-vnd.Haiku-Terminal";
18 const directory_which kAppsDirectory = B_SYSTEM_APPS_DIRECTORY;
20 void
21 launch_terminal(BEntry* targetEntry, BPath* terminalPath) {
23 BPath targetPath;
25 if (targetEntry->GetPath(&targetPath) != B_OK)
26 return;
28 // Escape paths which contain an apostraphe
29 BString target(targetPath.Path());
30 target.ReplaceAll("'", "'\\''");
32 BString terminal(terminalPath->Path());
33 terminal.ReplaceAll("'", "'\\''");
35 // Build the command to "cd '/my/target/folder'; '/path/to/Terminal' &"
36 BString command("cd '");
37 command << target << "'; '" << terminal << "' &";
39 // Launch the Terminal.
40 system(command.String());
44 void
45 process_refs(entry_ref base_ref, BMessage* message, void* reserved)
47 BPath terminalPath;
49 bool terminalFound = false;
51 // Search for Terminal path by asking BRoster.
52 entry_ref terminalRef;
53 if (be_roster->FindApp(kTerminalSignature, &terminalRef) == B_OK) {
54 if (terminalPath.SetTo(&terminalRef) == B_OK)
55 terminalFound = true;
58 // Fall back to manually creating a path if BRoster didn't find it.
59 if (!terminalFound) {
60 if (find_directory(kAppsDirectory, &terminalPath) != B_OK)
61 return;
63 if (terminalPath.Append("Terminal") != B_OK)
64 return;
67 BEntry entry;
68 int32 i;
69 entry_ref tracker_ref;
70 std::vector<BEntry> entries;
72 // Iterate through the refs that Tracker has sent us.
73 for (i = 0; message->FindRef("refs", i, &tracker_ref) == B_OK; i++) {
75 // Pass 'true' as the traverse argument below, so that if the ref
76 // is a symbolic link we get the target of the link to ensure that
77 // it actually exists.
78 if (entry.SetTo(&tracker_ref, true) != B_OK)
79 continue;
81 // If the entry is a file then look for the parent directory.
82 if (!entry.IsDirectory()) {
83 if (entry.GetParent(&entry) != B_OK)
84 continue;
87 bool duplicate = false;
89 // Check for duplicates.
90 for (uint x = 0; x < entries.size(); x++) {
91 if (entries[x] == entry) {
92 duplicate = true;
93 break;
97 // This is a duplicate. Continue to next ref.
98 if (duplicate)
99 continue;
101 // Push entry onto the vector so we can check for duplicates later.
102 entries.push_back(BEntry(entry));
104 launch_terminal(&entry, &terminalPath);
108 // If nothing was selected we'll use the base folder.
109 if (i == 0) {
110 if (entry.SetTo(&base_ref) == B_OK)
111 launch_terminal(&entry, &terminalPath);