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 <netdb.h>
10#include <pwd.h>
11#include <stdio.h>
12#include <string.h>
13#include <unistd.h>
14#include <iomanip>
15#include <sstream>
16
17#include "LpsClient.h"
18#include "LprSetupDlg.h"
19#include "LprTransport.h"
20#include "LprDefs.h"
21#include "DbgMsg.h"
22
23
24using namespace std;
25
26
27LprTransport::LprTransport(BMessage *msg)
28	:
29	BDataIO()
30{
31	fServer[0] = '\0';
32	fQueue[0]  = '\0';
33	fFile[0]   = '\0';
34	fUser[0]   = '\0';
35	fJobId     = 0;
36	fError     = false;
37
38	struct passwd *pwd = getpwuid(geteuid());
39	if (pwd != NULL && pwd->pw_name != NULL && pwd->pw_name[0])
40		strcpy(fUser, pwd->pw_name);
41	else
42		strcpy(fUser, "baron");
43
44	DUMP_BMESSAGE(msg);
45
46	const char *spool_path = msg->FindString(SPOOL_PATH);
47	if (spool_path && *spool_path) {
48		BDirectory dir(spool_path);
49		DUMP_BDIRECTORY(&dir);
50
51		dir.ReadAttr(LPR_SERVER_NAME, B_STRING_TYPE, 0, fServer, sizeof(fServer));
52		if (fServer[0] == '\0') {
53			LprSetupDlg *dlg = new LprSetupDlg(&dir);
54			if (dlg->Go() == B_ERROR) {
55				fError = true;
56				return;
57			}
58		}
59
60		dir.ReadAttr(LPR_SERVER_NAME, B_STRING_TYPE, 0, fServer, sizeof(fServer));
61		dir.ReadAttr(LPR_QUEUE_NAME,  B_STRING_TYPE, 0, fQueue,  sizeof(fQueue));
62		dir.ReadAttr(LPR_JOB_ID,      B_INT32_TYPE,  0, &fJobId, sizeof(fJobId));
63		fJobId++;
64		if (fJobId > 255) {
65			fJobId = 1;
66		}
67		dir.WriteAttr(LPR_JOB_ID, B_INT32_TYPE, 0, &fJobId, sizeof(fJobId));
68
69		sprintf(fFile, "%s/%s@ipp.%" B_PRId32, spool_path, fUser, fJobId);
70
71		fStream.open(fFile, ios::in | ios::out | ios::binary | ios::trunc);
72		if (fStream.good()) {
73			DBGMSG(("spool_file: %s\n", fFile));
74			return;
75		}
76	}
77	fError = true;
78}
79
80
81LprTransport::~LprTransport()
82{
83	if (!fError)
84		_SendFile();
85
86	if (fFile[0] != '\0')
87		unlink(fFile);
88}
89
90
91void
92LprTransport::_SendFile()
93{
94	char hostname[128];
95	if (gethostname(hostname, sizeof(hostname)) != B_OK)
96		strcpy(hostname, "localhost");
97
98	ostringstream cfname;
99	cfname << "cfA" << setw(3) << setfill('0') << fJobId << hostname;
100
101	ostringstream dfname;
102	dfname << "dfA" << setw(3) << setfill('0') << fJobId << hostname;
103
104	ostringstream cf;
105	cf << 'H' << hostname     << '\n';
106	cf << 'P' << fUser << '\n';
107	cf << 'l' << dfname.str() << '\n';
108	cf << 'U' << dfname.str() << '\n';
109
110	long cfsize = cf.str().length();
111	long dfsize = fStream.tellg();
112	fStream.seekg(0, ios::beg);
113
114	try {
115		LpsClient lpr(fServer);
116
117		lpr.connect();
118		lpr.receiveJob(fQueue);
119
120		lpr.receiveControlFile(cfsize, cfname.str().c_str());
121		lpr.transferData(cf.str().c_str(), cfsize);
122		lpr.endTransfer();
123
124		lpr.receiveDataFile(dfsize, dfname.str().c_str());
125		lpr.transferData(fStream, dfsize);
126		lpr.endTransfer();
127	}
128
129	catch (LPSException &err) {
130		DBGMSG(("error: %s\n", err.what()));
131		BAlert *alert = new BAlert("", err.what(), "OK");
132		alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
133		alert->Go();
134	}
135}
136
137
138ssize_t
139LprTransport::Read(void *, size_t)
140{
141	return 0;
142}
143
144
145ssize_t
146LprTransport::Write(const void *buffer, size_t size)
147{
148	if (!fStream.write((char *)buffer, size)) {
149		fError = true;
150		return 0;
151	}
152	return size;
153}
154