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