vfs: check userland buffers before reading them.
[haiku.git] / src / libs / print / libprint / Transport.cpp
blob0b082dc329cca4d9be8415604fc9a590a1c35dcd
1 /*
2 * Transport.cpp
3 * Copyright 1999-2000 Y.Takagi. All Rights Reserved.
4 */
6 #include <FindDirectory.h>
7 #include <Message.h>
8 #include <Directory.h>
9 #include <DataIO.h>
10 #include <File.h>
11 #include <Path.h>
12 #include <image.h>
14 #include "Transport.h"
15 #include "PrinterData.h"
16 #include "DbgMsg.h"
19 using namespace std;
22 TransportException::TransportException(const string& what)
24 fWhat(what)
29 const char*
30 TransportException::What() const
32 return fWhat.c_str();
36 Transport::Transport(const PrinterData *printerData)
38 fImage(-1),
39 fInitTransport(0),
40 fExitTransport(0),
41 fDataStream(0),
42 fAbort(false)
44 const directory_which paths[] = {
45 B_USER_NONPACKAGED_ADDONS_DIRECTORY,
46 B_USER_ADDONS_DIRECTORY,
47 B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY,
48 B_BEOS_ADDONS_DIRECTORY,
50 BPath path;
51 for (uint32 i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i) {
52 if (find_directory(paths[i], &path) != B_OK)
53 continue;
54 path.Append("Print/transport");
55 path.Append(printerData->GetTransport().c_str());
56 DBGMSG(("load_add_on: %s\n", path.Path()));
57 fImage = load_add_on(path.Path());
58 if (fImage >= 0)
59 break;
62 if (fImage < 0) {
63 SetLastError("cannot load a transport add-on");
64 return;
67 DBGMSG(("image id = %d\n", (int)fImage));
69 get_image_symbol(fImage, "init_transport", B_SYMBOL_TYPE_TEXT, (void **)&fInitTransport);
70 get_image_symbol(fImage, "exit_transport", B_SYMBOL_TYPE_TEXT, (void **)&fExitTransport);
72 if (fInitTransport == NULL) {
73 SetLastError("get_image_symbol failed.");
74 DBGMSG(("init_transport is NULL\n"));
77 if (fExitTransport == NULL) {
78 SetLastError("get_image_symbol failed.");
79 DBGMSG(("exit_transport is NULL\n"));
82 if (fInitTransport) {
83 string spool_path;
84 printerData->GetPath(spool_path);
85 BMessage *msg = new BMessage('TRIN');
86 msg->AddString("printer_file", spool_path.c_str());
87 fDataStream = (*fInitTransport)(msg);
88 delete msg;
89 if (fDataStream == 0) {
90 SetLastError("init_transport failed.");
96 Transport::~Transport()
98 if (fExitTransport) {
99 (*fExitTransport)();
101 if (fImage >= 0) {
102 unload_add_on(fImage);
107 bool
108 Transport::CheckAbort() const
110 return fDataStream == 0;
114 const
115 string &Transport::LastError() const
117 return fLastErrorString;
121 bool
122 Transport::IsPrintToFileCanceled() const
124 // The BeOS "Print To File" transport add-on returns a non-NULL BDataIO *
125 // even after user filepanel cancellation!
126 BFile* file = dynamic_cast<BFile*>(fDataStream);
127 return file != NULL && file->InitCheck() != B_OK;
131 void
132 Transport::SetLastError(const char *e)
134 fLastErrorString = e;
135 fAbort = true;
139 void
140 Transport::Write(const void* buffer, size_t size) throw(TransportException)
142 if (fDataStream) {
143 if (size == (size_t)fDataStream->Write(buffer, size)) {
144 return;
146 SetLastError("BDataIO::Write failed.");
148 throw TransportException(LastError());