vfs: check userland buffers before reading them.
[haiku.git] / src / tests / add-ons / print / transports / main.cpp
blob68e69ab4d1b9abc239c6060be185a1fe1b2113cd
1 #include <getopt.h>
2 #include <stdio.h>
4 #include <Application.h>
5 #include <DataIO.h>
6 #include <Directory.h>
7 #include <File.h>
8 #include <FindDirectory.h>
9 #include <image.h>
10 #include <Message.h>
11 #include <Path.h>
12 #include <PrintTransportAddOn.h>
14 static struct option longopts[] = {
15 { "help", no_argument, NULL, 'h' },
16 { "verbose", no_argument, NULL, 'v' },
17 { "list-ports", no_argument, NULL, 'p' },
18 { NULL, 0, NULL, 0 }
21 static int verbose = 0;
24 static void
25 usage(int argc, char** argv)
27 fprintf(stderr,
28 "Usage: %s [OPTIONS...] transport-addon-name [file to send]\n"
29 "\n"
30 " -p, --list-ports print ports detected by the transport add-on\n"
31 " -v, --verbose tell me more. Use multiple times for more details\n"
32 " -h, --help display this help and exit\n"
33 "\n", argv[0]
38 int main (int argc, char *argv[])
40 int c;
41 bool list_ports = false;
43 while ((c = getopt_long(argc, argv, "hvp", longopts, 0)) > 0) {
44 switch (c) {
45 case 'p':
46 list_ports = true;
47 break;
48 case 'v':
49 verbose++;
50 break;
51 default:
52 usage(argc, argv);
53 return 0;
56 argc -= optind;
57 argv += optind;
59 if (argc < 1) {
60 usage(argc, argv);
61 return -1;
64 new BApplication("application/x-vnd-Haiku-print_transport_tester");
66 image_id addon = -1;
67 char *transport = argv[0];
69 printf("Looking for %s transport addon:\n", transport);
71 directory_which which[] = {
72 B_USER_NONPACKAGED_ADDONS_DIRECTORY,
73 B_USER_ADDONS_DIRECTORY,
74 B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY,
75 B_SYSTEM_ADDONS_DIRECTORY
77 BPath path;
78 for (uint32 i = 0; i <sizeof(which) / sizeof(which[0]); i++) {
79 if (find_directory(which[i], &path, false) != B_OK)
80 continue;
82 path.Append("Print/transport");
83 path.Append(transport);
85 printf("\t%s ?\n", path.Path());
86 addon = load_add_on(path.Path());
87 if (addon >= B_OK)
88 break;
91 if (addon == B_ERROR) {
92 // failed to load transport add-on
93 printf("Failed to load \"%s\" print transport add-on!\n", transport);
94 return -1;
97 printf("Add-on %d = \"%s\" loaded from %s.\n", (int) addon,
98 transport, path.Path());
100 // get init & exit proc
101 BDataIO* (*transport_init_proc)(BMessage*) = NULL;
102 void (*transport_exit_proc)(void) = NULL;
103 status_t (*list_transport_ports)(BMessage*) = NULL;
104 int* transport_features_ptr = NULL;
106 get_image_symbol(addon, "init_transport", B_SYMBOL_TYPE_TEXT, (void **) &transport_init_proc);
107 get_image_symbol(addon, "exit_transport", B_SYMBOL_TYPE_TEXT, (void **) &transport_exit_proc);
109 get_image_symbol(addon, B_TRANSPORT_LIST_PORTS_SYMBOL, B_SYMBOL_TYPE_TEXT,
110 (void **) &list_transport_ports);
111 get_image_symbol(addon, B_TRANSPORT_FEATURES_SYMBOL, B_SYMBOL_TYPE_DATA,
112 (void **) &transport_features_ptr);
114 if (transport_init_proc == NULL || transport_exit_proc == NULL) {
115 // transport add-on has not the proper interface
116 printf("Invalid print transport add-on API!\n");
117 unload_add_on(addon);
118 return B_ERROR;
121 if (list_ports) {
122 printf("Ports list:\n");
124 if (list_transport_ports == NULL)
125 printf("Transport \"%s\" don't support this feature!\n", transport);
126 else {
127 BMessage ports;
128 snooze(1000000); // give some time for ports discovery
129 status_t status = (*list_transport_ports)(&ports);
130 if (status == B_OK)
131 ports.PrintToStream();
132 else
133 printf("failed!\n");
137 printf("Initing %s: ", transport);
139 // now, initialize the transport add-on
140 // request BDataIO object from transport add-on
141 BMessage msg('TRIN');
142 // TODO: create on the fly a temporary printer folder for testing purpose only
143 msg.AddString("printer_file", "/boot/home/config/settings/printers/test");
144 BDataIO *io = (*transport_init_proc)(&msg);
146 if (io) {
147 printf("done.\nTransport parameters msg =>\n");
148 msg.PrintToStream();
149 } else
150 printf("failed!\n");
153 if (argc > 1) {
154 BFile data(argv[1], B_READ_ONLY);
155 if (data.InitCheck() == B_OK) {
156 uint8 buffer[B_PAGE_SIZE];
157 ssize_t total = 0;
158 ssize_t sz;
160 printf("Sending data read from %s file...\n", argv[2]);
161 while((sz = data.Read(buffer, sizeof(buffer))) > 0) {
162 if (io->Write(buffer, sz) < 0) {
163 printf("Error writting on the print transport stream!\n");
164 break;
166 total += sz;
167 } // while
168 printf("%ld data bytes sent.\n", total);
169 } // data valid file
170 } // optional data file
172 if (transport_exit_proc) {
173 printf("Exiting %s...\n", transport);
174 (*transport_exit_proc)();
177 unload_add_on(addon);
178 printf("%s unloaded.\n", transport);
180 return B_OK;