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_ADDONS_DIRECTORY, 73 B_COMMON_ADDONS_DIRECTORY, 74 B_SYSTEM_ADDONS_DIRECTORY 75 }; 76 BPath path; 77 for (uint32 i = 0; i <sizeof(which) / sizeof(which[0]); i++) { 78 if (find_directory(which[i], &path, false) != B_OK) 79 continue; 80 81 path.Append("Print/transport"); 82 path.Append(transport); 83 84 printf("\t%s ?\n", path.Path()); 85 addon = load_add_on(path.Path()); 86 if (addon >= B_OK) 87 break; 88 } 89 90 if (addon == B_ERROR) { 91 // failed to load transport add-on 92 printf("Failed to load \"%s\" print transport add-on!\n", transport); 93 return -1; 94 } 95 96 printf("Add-on %d = \"%s\" loaded from %s.\n", (int) addon, 97 transport, path.Path()); 98 99 // get init & exit proc 100 BDataIO* (*transport_init_proc)(BMessage*) = NULL; 101 void (*transport_exit_proc)(void) = NULL; 102 status_t (*list_transport_ports)(BMessage*) = NULL; 103 int* transport_features_ptr = NULL; 104 105 get_image_symbol(addon, "init_transport", B_SYMBOL_TYPE_TEXT, (void **) &transport_init_proc); 106 get_image_symbol(addon, "exit_transport", B_SYMBOL_TYPE_TEXT, (void **) &transport_exit_proc); 107 108 get_image_symbol(addon, B_TRANSPORT_LIST_PORTS_SYMBOL, B_SYMBOL_TYPE_TEXT, 109 (void **) &list_transport_ports); 110 get_image_symbol(addon, B_TRANSPORT_FEATURES_SYMBOL, B_SYMBOL_TYPE_DATA, 111 (void **) &transport_features_ptr); 112 113 if (transport_init_proc == NULL || transport_exit_proc == NULL) { 114 // transport add-on has not the proper interface 115 printf("Invalid print transport add-on API!\n"); 116 unload_add_on(addon); 117 return B_ERROR; 118 } 119 120 if (list_ports) { 121 printf("Ports list:\n"); 122 123 if (list_transport_ports == NULL) 124 printf("Transport \"%s\" don't support this feature!\n", transport); 125 else { 126 BMessage ports; 127 snooze(1000000); // give some time for ports discovery 128 status_t status = (*list_transport_ports)(&ports); 129 if (status == B_OK) 130 ports.PrintToStream(); 131 else 132 printf("failed!\n"); 133 } 134 } 135 136 printf("Initing %s: ", transport); 137 138 // now, initialize the transport add-on 139 // request BDataIO object from transport add-on 140 BMessage msg('TRIN'); 141 // TODO: create on the fly a temporary printer folder for testing purpose only 142 msg.AddString("printer_file", "/boot/home/config/settings/printers/test"); 143 BDataIO *io = (*transport_init_proc)(&msg); 144 145 if (io) { 146 printf("done.\nTransport parameters msg =>\n"); 147 msg.PrintToStream(); 148 } else 149 printf("failed!\n"); 150 151 152 if (argc > 1) { 153 BFile data(argv[1], B_READ_ONLY); 154 if (data.InitCheck() == B_OK) { 155 uint8 buffer[B_PAGE_SIZE]; 156 ssize_t total = 0; 157 ssize_t sz; 158 159 printf("Sending data read from %s file...\n", argv[2]); 160 while((sz = data.Read(buffer, sizeof(buffer))) > 0) { 161 if (io->Write(buffer, sz) < 0) { 162 printf("Error writting on the print transport stream!\n"); 163 break; 164 } 165 total += sz; 166 } // while 167 printf("%ld data bytes sent.\n", total); 168 } // data valid file 169 } // optional data file 170 171 if (transport_exit_proc) { 172 printf("Exiting %s...\n", transport); 173 (*transport_exit_proc)(); 174 } 175 176 unload_add_on(addon); 177 printf("%s unloaded.\n", transport); 178 179 return B_OK; 180 } 181 182