xref: /haiku/src/tests/add-ons/print/transports/main.cpp (revision 21258e2674226d6aa732321b6f8494841895af5f)
1 #include <getopt.h>
2 #include <stdio.h>
3 
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>
13 
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   }
19 };
20 
21 static int verbose = 0;
22 
23 
24 static void
25 usage(int argc, char** argv)
26 {
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]
34 );
35 }
36 
37 
38 int main (int argc, char *argv[])
39 {
40 	int c;
41 	bool list_ports = false;
42 
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;
54 		}
55 	}
56     argc -= optind;
57     argv += optind;
58 
59     if (argc < 1) {
60 		usage(argc, argv);
61 		return -1;
62     }
63 
64 	new BApplication("application/x-vnd-Haiku-print_transport_tester");
65 
66 	image_id addon = -1;
67 	char *transport = argv[0];
68 
69 	printf("Looking for %s transport addon:\n", transport);
70 
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
76 	};
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;
81 
82 		path.Append("Print/transport");
83 		path.Append(transport);
84 
85 		printf("\t%s ?\n", path.Path());
86 		addon = load_add_on(path.Path());
87 		if (addon >= B_OK)
88 			break;
89 	}
90 
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;
95 	}
96 
97 	printf("Add-on %d = \"%s\" loaded from %s.\n", (int) addon,
98 		transport, path.Path());
99 
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;
105 
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);
108 
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);
113 
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;
119 	}
120 
121 	if (list_ports) {
122 		printf("Ports list:\n");
123 
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");
134 		}
135 	}
136 
137 	printf("Initing %s: ", transport);
138 
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);
145 
146 	if (io) {
147 		printf("done.\nTransport parameters msg =>\n");
148 		msg.PrintToStream();
149 	} else
150 		printf("failed!\n");
151 
152 
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;
159 
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;
165 				}
166 				total += sz;
167 			}	// while
168 			printf("%ld data bytes sent.\n", total);
169 		}	// data valid file
170 	}	// optional data file
171 
172 	if (transport_exit_proc) {
173 		printf("Exiting %s...\n", transport);
174 		(*transport_exit_proc)();
175 	}
176 
177 	unload_add_on(addon);
178 	printf("%s unloaded.\n", transport);
179 
180 	return B_OK;
181 }
182 
183