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