1 // Sun, 18 Jun 2000 2 // Y.Takagi 3 4 #if defined(__HAIKU__) || defined(HAIKU_TARGET_PLATFORM_BONE) 5 # include <sys/socket.h> 6 # include <netdb.h> 7 #else 8 # include <net/socket.h> 9 # include <net/netdb.h> 10 #endif 11 12 #include <errno.h> 13 #include <string.h> 14 15 #include <iomanip> 16 #include <algorithm> 17 #include "LpsClient.h" 18 #include "Socket.h" 19 //#include "DbgMsg.h" 20 21 #if (!__MWERKS__) 22 using namespace std; 23 #else 24 #define std 25 #endif 26 27 #define LPS_SERVER_PORT 515 28 #define LPS_CLIENT_PORT_S 721 29 #define LPS_CLIENT_PORT_E 731 30 31 #define LPS_CHECK_QUEUE '\001' 32 #define LPS_PRINT_JOB '\002' 33 #define LPS_DISPLAY_SHORT_QUEUE '\003' 34 #define LPS_DISPLAY_LONG_QUEUE '\004' 35 #define LPS_REMOVE_JOB '\005' 36 #define LPS_END_TRANSFER '\000' 37 #define LPS_ABORT '\001' 38 #define LPS_RECEIVE_CONTROL_FILE '\002' 39 #define LPS_RECEIVE_DATA_FILE '\003' 40 41 #define LPS_OK '\0' 42 #define LPS_ERROR '\1' 43 #define LPS_NO_SPOOL_SPACE '\2' 44 45 #ifndef INADDR_NONE 46 #define INADDR_NONE 0xffffffff 47 #endif 48 49 #define ERRNO errno 50 51 52 LpsClient::LpsClient(const char *host) 53 : connected(false), __host(host), __sock(NULL) 54 { 55 } 56 57 LpsClient::~LpsClient() 58 { 59 close(); 60 } 61 62 void LpsClient::connect() throw(LPSException) 63 { 64 // DBGMSG(("connect\n")); 65 66 for (int localPort = LPS_CLIENT_PORT_S ; localPort <= LPS_CLIENT_PORT_E ; localPort++) { 67 if (__sock) { 68 delete __sock; 69 } 70 __sock = new Socket(__host.c_str(), LPS_SERVER_PORT, localPort); 71 if (__sock->good()) { 72 __is = &__sock->getInputStream(); 73 __os = &__sock->getOutputStream(); 74 connected = true; 75 return; 76 } 77 } 78 79 throw(LPSException(__sock->getLastError())); 80 } 81 82 void LpsClient::close() 83 { 84 // DBGMSG(("close\n")); 85 86 connected = false; 87 if (__sock) { 88 delete __sock; 89 __sock = NULL; 90 } 91 } 92 93 void LpsClient::receiveJob(const char *printer) throw(LPSException) 94 { 95 // DBGMSG(("tell_receive_job\n")); 96 97 if (connected) { 98 *__os << LPS_PRINT_JOB << printer << '\n' << flush; 99 checkAck(); 100 } 101 } 102 103 void LpsClient::receiveControlFile(int size, const char *name) throw(LPSException) 104 { 105 // DBGMSG(("tell_receive_control_file\n")); 106 107 if (connected) { 108 109 char cfname[32]; 110 strncpy(cfname, name, sizeof(cfname)); 111 cfname[sizeof(cfname) - 1] = '\0'; 112 113 *__os << LPS_RECEIVE_CONTROL_FILE << size << ' ' << cfname << '\n' << flush; 114 115 checkAck(); 116 } 117 } 118 119 void LpsClient::receiveDataFile(int size, const char *name) throw(LPSException) 120 { 121 // DBGMSG(("tell_receive_data_file\n")); 122 123 if (connected) { 124 125 char dfname[32]; 126 strncpy(dfname, name, sizeof(dfname)); 127 dfname[sizeof(dfname) - 1] = '\0'; 128 129 *__os << LPS_RECEIVE_DATA_FILE << size << ' ' << dfname << '\n' << flush; 130 131 checkAck(); 132 } 133 } 134 135 void LpsClient::transferData(const char *buffer, int size) throw(LPSException) 136 { 137 // DBGMSG(("send: %d\n", size)); 138 139 if (connected) { 140 141 if (size < 0) { 142 size = strlen(buffer); 143 } 144 145 if (!__os->write(buffer, size)) { 146 close(); 147 throw(LPSException("error talking to lpd server")); 148 } 149 } 150 } 151 152 void LpsClient::transferData(istream &is, int size) throw(LPSException) 153 { 154 // DBGMSG(("send: %d\n", size)); 155 156 if (connected) { 157 158 if (size < 0) { 159 is.seekg(0, ios::end); 160 size = is.tellg(); 161 is.seekg(0, ios::beg); 162 } 163 164 char c; 165 while (is.get(c)) { 166 if (!__os->put(c)) { 167 close(); 168 throw(LPSException("error reading file.")); 169 return; 170 } 171 } 172 } 173 } 174 175 void LpsClient::endTransfer() throw(LPSException) 176 { 177 // DBGMSG(("tell_end_transfer\n")); 178 179 if (connected) { 180 *__os << LPS_END_TRANSFER << flush; 181 checkAck(); 182 } 183 } 184 185 void LpsClient::checkAck() throw(LPSException) 186 { 187 // DBGMSG(("check_ack\n")); 188 189 if (connected) { 190 191 char c; 192 193 if (!__is->get(c)) { 194 close(); 195 throw(LPSException("server not responding.")); 196 return; 197 } 198 199 switch (c) { 200 case LPS_OK: 201 break; 202 case LPS_ERROR: 203 close(); 204 throw(LPSException("server error.")); 205 break; 206 case LPS_NO_SPOOL_SPACE: 207 close(); 208 throw(LPSException("not enough spool space on server.")); 209 break; 210 } 211 } 212 } 213