xref: /haiku/src/add-ons/print/transports/lpr/LprTransport.cpp (revision 7749d0bb0c358a3279b1b9cc76d8376e900130a5)
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 
24 using namespace std;
25 
26 
27 LprTransport::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.%ld", 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 
81 LprTransport::~LprTransport()
82 {
83 	if (!fError)
84 		_SendFile();
85 
86 	if (fFile[0] != '\0')
87 		unlink(fFile);
88 }
89 
90 
91 void
92 LprTransport::_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->Go();
133 	}
134 }
135 
136 
137 ssize_t
138 LprTransport::Read(void *, size_t)
139 {
140 	return 0;
141 }
142 
143 
144 ssize_t
145 LprTransport::Write(const void *buffer, size_t size)
146 {
147 	if (!fStream.write((char *)buffer, size)) {
148 		fError = true;
149 		return 0;
150 	}
151 	return size;
152 }
153