vfs: check userland buffers before reading them.
[haiku.git] / src / servers / print / PrintServerApp.Scripting.cpp
blob531f7efc37f5ef9d8eecebabd07b90a897534b8a
1 /*
2 * Copyright 2001-2006, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Ithamar R. Adema
7 */
10 #include "PrintServerApp.h"
12 #include <stdio.h>
14 #include <Catalog.h>
15 #include <Locale.h>
16 #include <PropertyInfo.h>
18 #include "Transport.h"
19 #include "Printer.h"
22 #undef B_TRANSLATION_CONTEXT
23 #define B_TRANSLATION_CONTEXT "PrintServerApp Scripting"
26 static property_info prop_list[] = {
27 { "ActivePrinter", { B_GET_PROPERTY, B_SET_PROPERTY },
28 { B_DIRECT_SPECIFIER },
29 B_TRANSLATE_MARK("Retrieve or select the active printer") },
30 { "Printer", { B_GET_PROPERTY }, { B_INDEX_SPECIFIER, B_NAME_SPECIFIER,
31 B_REVERSE_INDEX_SPECIFIER },
32 B_TRANSLATE_MARK("Retrieve a specific printer") },
33 { "Printer", { B_CREATE_PROPERTY }, { B_DIRECT_SPECIFIER },
34 B_TRANSLATE_MARK("Create a new printer") },
35 { "Printer", { B_DELETE_PROPERTY }, { B_INDEX_SPECIFIER, B_NAME_SPECIFIER,
36 B_REVERSE_INDEX_SPECIFIER },
37 B_TRANSLATE_MARK("Delete a specific printer") },
38 { "Printers", { B_COUNT_PROPERTIES }, { B_DIRECT_SPECIFIER },
39 B_TRANSLATE_MARK("Return the number of available printers") },
40 { "Transport", { B_GET_PROPERTY }, { B_INDEX_SPECIFIER, B_NAME_SPECIFIER,
41 B_REVERSE_INDEX_SPECIFIER },
42 B_TRANSLATE_MARK("Retrieve a specific transport") },
43 { "Transports", { B_COUNT_PROPERTIES }, { B_DIRECT_SPECIFIER },
44 B_TRANSLATE_MARK("Return the number of available transports") },
45 { "UseConfigWindow", { B_GET_PROPERTY, B_SET_PROPERTY },
46 { B_DIRECT_SPECIFIER },
47 B_TRANSLATE_MARK("Show configuration window") },
49 { 0 } // terminate list
53 void
54 PrintServerApp::HandleScriptingCommand(BMessage* msg)
56 BString propName;
57 BMessage spec;
58 int32 idx;
60 if (msg->GetCurrentSpecifier(&idx,&spec) == B_OK &&
61 spec.FindString("property",&propName) == B_OK) {
62 switch(msg->what) {
63 case B_GET_PROPERTY:
64 if (propName == "ActivePrinter") {
65 BMessage reply(B_REPLY);
66 reply.AddString("result", fDefaultPrinter
67 ? fDefaultPrinter->Name() : "");
68 reply.AddInt32("error", B_OK);
69 msg->SendReply(&reply);
70 } else if (propName == "UseConfigWindow") {
71 BMessage reply(B_REPLY);
72 reply.AddString("result", fUseConfigWindow
73 ? "true" : "false");
74 reply.AddInt32("error", B_OK);
75 msg->SendReply(&reply);
77 break;
79 case B_SET_PROPERTY:
80 if (propName == "ActivePrinter") {
81 BString newActivePrinter;
82 if (msg->FindString("data", &newActivePrinter) == B_OK) {
83 BMessage reply(B_REPLY);
84 reply.AddInt32("error",
85 SelectPrinter(newActivePrinter.String()));
86 msg->SendReply(&reply);
88 } else if (propName == "UseConfigWindow") {
89 bool useConfigWindow;
90 if (msg->FindBool("data", &useConfigWindow) == B_OK) {
91 fUseConfigWindow = useConfigWindow;
92 BMessage reply(B_REPLY);
93 reply.AddInt32("error", fUseConfigWindow);
94 msg->SendReply(&reply);
97 break;
99 case B_CREATE_PROPERTY:
100 if (propName == "Printer") {
101 BString name, driver, transport, config;
103 if (msg->FindString("name", &name) == B_OK
104 && msg->FindString("driver", &driver) == B_OK
105 && msg->FindString("transport", &transport) == B_OK
106 && msg->FindString("config", &config) == B_OK) {
107 BMessage reply(B_REPLY);
108 reply.AddInt32("error", CreatePrinter(name.String(),
109 driver.String(), "Local", transport.String(),
110 config.String()));
111 msg->SendReply(&reply);
114 break;
116 case B_DELETE_PROPERTY: {
117 Printer* printer = GetPrinterFromSpecifier(&spec);
118 status_t rc = B_BAD_VALUE;
120 if (printer != NULL)
121 rc=printer->Remove();
123 BMessage reply(B_REPLY);
124 reply.AddInt32("error", rc);
125 msg->SendReply(&reply);
127 break;
129 case B_COUNT_PROPERTIES:
130 if (propName == "Printers") {
131 BMessage reply(B_REPLY);
132 reply.AddInt32("result", Printer::CountPrinters());
133 reply.AddInt32("error", B_OK);
134 msg->SendReply(&reply);
135 } else if (propName == "Transports") {
136 BMessage reply(B_REPLY);
137 reply.AddInt32("result", Transport::CountTransports());
138 reply.AddInt32("error", B_OK);
139 msg->SendReply(&reply);
141 break;
147 Printer*
148 PrintServerApp::GetPrinterFromSpecifier(BMessage* msg)
150 switch(msg->what) {
151 case B_NAME_SPECIFIER:
153 BString name;
154 if (msg->FindString("name", &name) == B_OK)
155 return Printer::Find(name.String());
156 break;
159 case B_INDEX_SPECIFIER:
161 int32 idx;
162 if (msg->FindInt32("index", &idx) == B_OK)
163 return Printer::At(idx);
164 break;
167 case B_REVERSE_INDEX_SPECIFIER:
169 int32 idx;
170 if (msg->FindInt32("index", &idx) == B_OK)
171 return Printer::At(Printer::CountPrinters() - idx);
172 break;
176 return NULL;
180 Transport*
181 PrintServerApp::GetTransportFromSpecifier(BMessage* msg)
183 switch(msg->what) {
184 case B_NAME_SPECIFIER:
186 BString name;
187 if (msg->FindString("name", &name) == B_OK)
188 return Transport::Find(name);
189 break;
192 case B_INDEX_SPECIFIER:
194 int32 idx;
195 if (msg->FindInt32("index", &idx) == B_OK)
196 return Transport::At(idx);
197 break;
200 case B_REVERSE_INDEX_SPECIFIER:
202 int32 idx;
203 if (msg->FindInt32("index", &idx) == B_OK)
204 return Transport::At(Transport::CountTransports() - idx);
205 break;
209 return NULL;
213 BHandler*
214 PrintServerApp::ResolveSpecifier(BMessage* msg, int32 index, BMessage* spec,
215 int32 form, const char* prop)
217 BPropertyInfo prop_info(prop_list);
218 BHandler* rc = NULL;
220 int32 idx;
221 switch( idx=prop_info.FindMatch(msg,0,spec,form,prop) ) {
222 case B_ERROR:
223 rc = Inherited::ResolveSpecifier(msg,index,spec,form,prop);
224 break;
226 case 1:
227 // GET Printer [arg]
228 if ((rc=GetPrinterFromSpecifier(spec)) == NULL) {
229 BMessage reply(B_REPLY);
230 reply.AddInt32("error", B_BAD_INDEX);
231 msg->SendReply(&reply);
233 else
234 msg->PopSpecifier();
235 break;
237 case 5:
238 // GET Transport [arg]
239 if ((rc=GetTransportFromSpecifier(spec)) == NULL) {
240 BMessage reply(B_REPLY);
241 reply.AddInt32("error", B_BAD_INDEX);
242 msg->SendReply(&reply);
244 else
245 msg->PopSpecifier();
246 break;
248 default:
249 rc = this;
252 return rc;
256 status_t
257 PrintServerApp::GetSupportedSuites(BMessage* msg)
259 msg->AddString("suites", "suite/vnd.OpenBeOS-printserver");
261 static bool localized = false;
262 if (!localized) {
263 localized = true;
264 for (int i = 0; prop_list[i].name != NULL; i ++)
265 prop_list[i].usage = B_TRANSLATE_NOCOLLECT(prop_list[i].usage);
268 BPropertyInfo prop_info(prop_list);
269 msg->AddFlat("messages", &prop_info);
271 return Inherited::GetSupportedSuites(msg);