vfs: check userland buffers before reading them.
[haiku.git] / src / bin / open.cpp
blob916e80692b37baec6a00cc18e181d749350ecbb9
1 /*
2 * Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de.
3 * Copyright 2005-2007, François Revol, revol@free.fr.
4 * Copyright 2009, Jonas Sundström, jonas@kirilla.com.
5 * Copyright 2014 Haiku, Inc. All rights reserved.
7 * Distributed under the terms of the MIT License.
9 * Authors:
10 * Axel Dörfler, axeld@pinc-software.de
11 * François Revol, revol@free.fr
12 * John Scipione, jscipione@gmail.com
13 * Jonas Sundström, jonas@kirilla.com
16 /*! Launches an application/document from the shell */
19 #include <errno.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <strings.h>
24 #include <Entry.h>
25 #include <List.h>
26 #include <Mime.h>
27 #include <Roster.h>
28 #include <String.h>
29 #include <Url.h>
31 #include <tracker_private.h>
34 status_t
35 open_file(const char* openWith, BEntry& entry, int32 line = -1, int32 col = -1)
37 entry_ref ref;
38 status_t result = entry.GetRef(&ref);
39 if (result != B_OK)
40 return result;
42 BMessenger target(openWith != NULL ? openWith : kTrackerSignature);
43 if (!target.IsValid())
44 return be_roster->Launch(&ref);
46 BMessage message(B_REFS_RECEIVED);
47 message.AddRef("refs", &ref);
48 if (line > -1)
49 message.AddInt32("be:line", line);
51 if (col > -1)
52 message.AddInt32("be:column", col);
54 // tell the app to open the file
55 return target.SendMessage(&message);
59 int
60 main(int argc, char** argv)
62 int exitCode = EXIT_SUCCESS;
63 const char* openWith = NULL;
65 char* progName = argv[0];
66 if (strrchr(progName, '/'))
67 progName = strrchr(progName, '/') + 1;
69 if (argc < 2) {
70 fprintf(stderr,"usage: %s <file[:line[:column]] or url or application "
71 "signature> ...\n", progName);
74 while (*++argv) {
75 status_t result = B_OK;
76 argc--;
78 BEntry entry(*argv);
79 if ((result = entry.InitCheck()) == B_OK && entry.Exists()) {
80 result = open_file(openWith, entry);
81 } else if (!strncasecmp("application/", *argv, 12)) {
82 // maybe it's an application-mimetype?
84 // subsequent files are open with that app
85 openWith = *argv;
87 // in the case the app is already started,
88 // don't start it twice if we have other args
89 BList teams;
90 if (argc > 1)
91 be_roster->GetAppList(*argv, &teams);
93 if (teams.IsEmpty())
94 result = be_roster->Launch(*argv);
95 else
96 result = B_OK;
97 } else if (strchr(*argv, ':')) {
98 // try to open it as an URI
99 BUrl url(*argv);
100 if (url.OpenWithPreferredApplication() == B_OK)
101 continue;
103 // maybe it's "file:line" or "file:line:col"
104 int line = 0, col = 0, i;
105 result = B_ENTRY_NOT_FOUND;
106 // remove gcc error's last :
107 BString arg(*argv);
108 if (arg[arg.Length() - 1] == ':')
109 arg.Truncate(arg.Length() - 1);
111 i = arg.FindLast(':');
112 if (i > 0) {
113 line = atoi(arg.String() + i + 1);
114 arg.Truncate(i);
116 result = entry.SetTo(arg.String());
117 if (result == B_OK && entry.Exists()) {
118 result = open_file(openWith, entry, line);
119 if (result == B_OK)
120 continue;
123 // get the column
124 col = line;
125 i = arg.FindLast(':');
126 line = atoi(arg.String() + i + 1);
127 arg.Truncate(i);
129 result = entry.SetTo(arg.String());
130 if (result == B_OK && entry.Exists())
131 result = open_file(openWith, entry, line, col);
133 } else
134 result = B_ENTRY_NOT_FOUND;
136 if (result != B_OK && result != B_ALREADY_RUNNING) {
137 fprintf(stderr, "%s: \"%s\": %s\n", progName, *argv,
138 strerror(result));
139 // make sure the shell knows this
140 exitCode = EXIT_FAILURE;
144 return exitCode;