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