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