1 // Sun, 18 Jun 2000 2 // Y.Takagi 3 4 #include <DataIO.h> 5 #include <Message.h> 6 #include <Directory.h> 7 #include <net/netdb.h> 8 #include <Alert.h> 9 #include <stdio.h> 10 #include <unistd.h> 11 12 #include "URL.h" 13 #include "IppContent.h" 14 #include "IppURLConnection.h" 15 #include "IppSetupDlg.h" 16 #include "IppTransport.h" 17 #include "IppDefs.h" 18 #include "DbgMsg.h" 19 20 #if (!__MWERKS__ || defined(WIN32)) 21 using namespace std; 22 #else 23 #define std 24 #endif 25 26 IppTransport::IppTransport(BMessage *msg) 27 : BDataIO() 28 { 29 __url[0] = '\0'; 30 __user[0] = '\0'; 31 __file[0] = '\0'; 32 __jobid = 0; 33 __error = false; 34 35 DUMP_BMESSAGE(msg); 36 37 const char *spool_path = msg->FindString(SPOOL_PATH); 38 if (spool_path && *spool_path) { 39 BDirectory dir(spool_path); 40 DUMP_BDIRECTORY(&dir); 41 42 dir.ReadAttr(IPP_URL, B_STRING_TYPE, 0, __url, sizeof(__url)); 43 if (__url[0] == '\0') { 44 IppSetupDlg *dlg = new IppSetupDlg(&dir); 45 if (dlg->Go() == B_ERROR) { 46 __error = true; 47 return; 48 } 49 } 50 51 dir.ReadAttr(IPP_URL, B_STRING_TYPE, 0, __url, sizeof(__url)); 52 dir.ReadAttr(IPP_JOB_ID, B_INT32_TYPE, 0, &__jobid, sizeof(__jobid)); 53 __jobid++; 54 if (__jobid > 255) { 55 __jobid = 1; 56 } 57 dir.WriteAttr(IPP_JOB_ID, B_INT32_TYPE, 0, &__jobid, sizeof(__jobid)); 58 59 getusername(__user, sizeof(__user)); 60 if (__user[0] == '\0') { 61 strcpy(__user, "baron"); 62 } 63 64 sprintf(__file, "%s/%s@ipp.%ld", spool_path, __user, __jobid); 65 66 __fs.open(__file, ios::in | ios::out | ios::binary | ios::trunc); 67 if (__fs.good()) { 68 DBGMSG(("spool_file: %s\n", __file)); 69 return; 70 } 71 } 72 __error = true; 73 } 74 75 IppTransport::~IppTransport() 76 { 77 string error_msg; 78 79 if (!__error && __fs.good()) { 80 DBGMSG(("create IppContent\n")); 81 IppContent *request = new IppContent; 82 request->setOperationId(IPP_PRINT_JOB); 83 request->setDelimiter(IPP_OPERATION_ATTRIBUTES_TAG); 84 request->setCharset("attributes-charset", "utf-8"); 85 request->setNaturalLanguage("attributes-natural-language", "en-us"); 86 request->setURI("printer-uri", __url); 87 request->setMimeMediaType("document-format", "application/octet-stream"); 88 request->setNameWithoutLanguage("requesting-user-name", __user); 89 // request->setNameWithoutLanguage("job-name", __file); // optional 90 request->setDelimiter(IPP_END_OF_ATTRIBUTES_TAG); 91 92 long fssize = __fs.tellg(); 93 __fs.seekg(0, ios::beg); 94 request->setRawData(__fs, fssize); 95 96 URL url(__url); 97 IppURLConnection conn(url); 98 conn.setIppRequest(request); 99 conn.setRequestProperty("Connection", "close"); 100 101 DBGMSG(("do connect\n")); 102 103 HTTP_RESPONSECODE response_code = conn.getResponseCode(); 104 if (response_code == HTTP_OK) { 105 const char *content_type = conn.getContentType(); 106 if (content_type && !strncasecmp(content_type, "application/ipp", 15)) { 107 const IppContent *ipp_response = conn.getIppResponse(); 108 if (ipp_response->fail()) { 109 __error = true; 110 error_msg = ipp_response->getStatusMessage(); 111 } 112 } else { 113 __error = true; 114 error_msg = "cannot get a IPP response."; 115 } 116 } else if (response_code != HTTP_UNKNOWN) { 117 __error = true; 118 error_msg = conn.getResponseMessage(); 119 } else { 120 __error = true; 121 error_msg = "cannot connect to the IPP server."; 122 } 123 } 124 125 unlink(__file); 126 127 if (__error) { 128 BAlert *alert = new BAlert("", error_msg.c_str(), "OK"); 129 alert->Go(); 130 } 131 } 132 133 ssize_t IppTransport::Read(void *, size_t) 134 { 135 return 0; 136 } 137 138 ssize_t IppTransport::Write(const void *buffer, size_t size) 139 { 140 // DBGMSG(("write: %d\n", size)); 141 142 if (!__fs.write(buffer, size)) { 143 __error = true; 144 return 0; 145 } 146 // return __fs.pcount(); 147 return size; 148 } 149