vfs: check userland buffers before reading them.
[haiku.git] / src / tools / fs_shell / external_commands_beos.cpp
blob84b66e367a9e1e1bc4d1d430699a89443f9c2d9f
1 /*
2 * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
3 * Distributed under the terms of the MIT License.
4 */
6 #include <stdio.h>
7 #include <string.h>
9 #include <OS.h>
11 #include "external_commands.h"
12 #include "fs_shell_command_beos.h"
15 static port_id sReplyPort = -1;
18 static port_id
19 get_command_port()
21 static port_id port = -1;
22 static bool initialized = false;
24 if (!initialized) {
25 port = create_port(10, kFSShellCommandPort);
26 initialized = true;
29 return port;
33 bool
34 FSShell::get_external_command(char *input, int len)
36 // get/create the port
37 port_id port = get_command_port();
38 if (port < 0) {
39 fprintf(stderr, "Error: Failed to create command port: %s\n",
40 strerror(port));
41 return false;
44 while (true) {
45 // read a message
46 char _message[sizeof(external_command_message) + kMaxCommandLength];
47 external_command_message* message = (external_command_message*)_message;
48 ssize_t bytesRead;
49 do {
50 int32 code;
51 bytesRead = read_port(port, &code, message, sizeof(_message));
52 } while (bytesRead == B_INTERRUPTED);
54 if (bytesRead < 0) {
55 fprintf(stderr, "Error: Reading from port failed: %s\n",
56 strerror(bytesRead));
57 return false;
60 // get the len of the command
61 int commandLen = _message + bytesRead - message->command;
62 if (commandLen <= 1) {
63 fprintf(stderr, "Error: No command given.\n");
64 continue;
66 if (commandLen > len) {
67 fprintf(stderr, "Error: Command too long. Ignored.\n");
68 continue;
71 // copy the command
72 memcpy(input, message->command, commandLen);
73 input[len - 1] = '\0'; // always NULL-terminate
74 sReplyPort = message->reply_port;
75 return true;
80 void
81 FSShell::reply_to_external_command(int result)
83 if (sReplyPort >= 0) {
84 // prepare the message
85 external_command_reply reply;
86 reply.error = result;
88 // send the reply
89 status_t error;
90 do {
91 error = write_port(sReplyPort, 0, &reply, sizeof(reply));
92 } while (error == B_INTERRUPTED);
93 sReplyPort = -1;
95 if (error != B_OK) {
96 fprintf(stderr, "Error: Failed to send command result to reply "
97 "port: %s\n", strerror(error));
103 void
104 FSShell::external_command_cleanup()
106 // The port will be deleted automatically when the team exits.