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