vfs: check userland buffers before reading them.
[haiku.git] / src / servers / print / Transport.cpp
blob3b59cefec0047b1a3f37d8a4c5c33fd94f1f162c
1 /*
2 * Copyright 2008, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Ithamar R. Adema
7 */
9 #include "Transport.h"
11 // BeOS API
12 #include <PrintTransportAddOn.h>
13 #include <Application.h>
14 #include <image.h>
15 #include <Entry.h>
18 BObjectList<Transport> Transport::sTransports;
21 // ---------------------------------------------------------------
22 // Find [static]
24 // Searches the static object list for a transport object with the
25 // specified name.
27 // Parameters:
28 // name - Printer definition name we're looking for.
30 // Returns:
31 // Pointer to Transport object, or NULL if not found.
32 // ---------------------------------------------------------------
33 Transport*
34 Transport::Find(const BString& name)
36 // Look in list to find printer definition
37 for (int32 index = 0; index < sTransports.CountItems(); index++) {
38 if (name == sTransports.ItemAt(index)->Name())
39 return sTransports.ItemAt(index);
42 // None found, so return NULL
43 return NULL;
47 Transport*
48 Transport::At(int32 index)
50 return sTransports.ItemAt(index);
54 void
55 Transport::Remove(Transport* transport)
57 sTransports.RemoveItem(transport);
61 int32
62 Transport::CountTransports()
64 return sTransports.CountItems();
68 status_t
69 Transport::Scan(directory_which which)
71 status_t result;
72 BPath path;
74 // Try to find specified transport addon directory
75 if ((result = find_directory(which, &path)) != B_OK)
76 return result;
78 if ((result = path.Append("Print/transport")) != B_OK)
79 return result;
81 BDirectory dir;
82 if ((result = dir.SetTo(path.Path())) != B_OK)
83 return result;
85 // Walk over all entries in directory
86 BEntry entry;
87 while(dir.GetNextEntry(&entry) == B_OK) {
88 if (!entry.IsFile())
89 continue;
91 if (entry.GetPath(&path) != B_OK)
92 continue;
94 // If we have loaded the transport from a previous scanned directory,
95 // ignore this one.
96 if (Transport::Find(path.Leaf()) != NULL)
97 continue;
99 be_app->AddHandler(new Transport(path));
102 return B_OK;
106 // ---------------------------------------------------------------
107 // Transport [constructor]
109 // Initializes the transport object with data read from the
110 // attributes attached to the printer definition node.
112 // Parameters:
113 // node - Printer definition node for this printer.
115 // Returns:
116 // none.
117 // ---------------------------------------------------------------
118 Transport::Transport(const BPath& path)
119 : BHandler(B_EMPTY_STRING),
120 fPath(path),
121 fImageID(-1),
122 fFeatures(0)
124 // Load transport addon
125 image_id id = ::load_add_on(path.Path());
126 if (id < B_OK)
127 return;
129 // Find transport_features symbol, to determine if we need to keep
130 // this transport loaded
131 int* transportFeaturesPointer;
132 if (get_image_symbol(id, B_TRANSPORT_FEATURES_SYMBOL,
133 B_SYMBOL_TYPE_DATA, (void**)&transportFeaturesPointer) != B_OK) {
134 unload_add_on(id);
135 } else {
136 fFeatures = *transportFeaturesPointer;
138 if (fFeatures & B_TRANSPORT_IS_HOTPLUG) {
139 // We are hotpluggable; so keep us loaded!
140 fImageID = id;
141 } else {
142 // No extended Transport support; so no need to keep loaded
143 ::unload_add_on(id);
147 sTransports.AddItem(this);
151 Transport::~Transport()
153 sTransports.RemoveItem(this);
157 status_t
158 Transport::ListAvailablePorts(BMessage* msg)
160 status_t (*list_ports)(BMessage*);
161 image_id id = fImageID;
162 status_t rc = B_OK;
164 // Load image if not loaded yet
165 if (id == -1 && (id = load_add_on(fPath.Path())) < 0)
166 return id;
168 // Get pointer to addon function
169 if ((rc = get_image_symbol(id, B_TRANSPORT_LIST_PORTS_SYMBOL,
170 B_SYMBOL_TYPE_TEXT, (void**)&list_ports)) != B_OK)
171 goto done;
173 // run addon...
174 rc = (*list_ports)(msg);
176 done:
177 // clean up if needed
178 if (fImageID != id)
179 unload_add_on(id);
181 return rc;
185 // ---------------------------------------------------------------
186 // MessageReceived
188 // Handle scripting messages.
190 // Parameters:
191 // msg - message.
192 // ---------------------------------------------------------------
193 void
194 Transport::MessageReceived(BMessage* msg)
196 switch(msg->what) {
197 case B_GET_PROPERTY:
198 case B_SET_PROPERTY:
199 case B_CREATE_PROPERTY:
200 case B_DELETE_PROPERTY:
201 case B_COUNT_PROPERTIES:
202 case B_EXECUTE_PROPERTY:
203 HandleScriptingCommand(msg);
204 break;
206 default:
207 Inherited::MessageReceived(msg);