File: pike2.pmod

package info (click to toggle)
ohcount 3.0.0-2
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 4,712 kB
  • ctags: 3,205
  • sloc: ansic: 6,524; ruby: 2,560; perl: 2,041; erlang: 350; lisp: 272; sh: 244; pascal: 196; vhdl: 150; haskell: 149; asm: 128; cs: 124; awk: 98; java: 92; php: 73; tcl: 58; xml: 57; fortran: 54; makefile: 32; python: 31; ada: 30; objc: 30; jsp: 28; sql: 18; cobol: 13; ml: 9; cpp: 3
file content (241 lines) | stat: -rw-r--r-- 5,489 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
//
// LPD.pmod: an implementation of the BSD lpd protocol (RFC 1179).
// This is a module for pike.
// 3 July 1998 <hww3@riverweb.com> Bill Welliver
//
// $Id: LPD.pmod,v 1.10 2008/01/13 17:02:43 nilsson Exp $
//

#pike __REAL_VERSION__

//! A client for communicating with printers and print spoolers that
//! support the BSD lpd protocol (RFC 1179).
class client {
  string host;
  int port;
  private object conn;
  int jobnum;
  string jobtype;
  string jobname;

  private int connect(string host, int port)
  {
    int a=random(10);
    // try to open one of the "official" local socket ports.
    // not having one doesn't seem to be a problem with most LPD 
    // servers, but we should at least try. will probably fail
    // if two try to open the same local port at once. ymmv.
    int res=conn->open_socket(721 + a);

    return conn->connect(host, port);
  }

//! @decl int set_job_type(string type)
//! Set the type of job to be sent to the printer to @i{type@}.
//! Valid types are: text, postscript and raw.
  int set_job_type(string type)
  {
    type=lower_case(type);
    
    switch (type) { 
     case "f":
     case "text":
      jobtype="f";
      break;

     case "o":
     case "postscript":
     case "ps":
      jobtype="o";
      break;

     default:
     case "l":
     case "raw":
      jobtype="l";
      break;
    }
    return 1;
  }

//! @decl int set_job_name(string name)
//! Sets the name of the print job to @i{name@}.
  int set_job_name(string name)
  {
    jobname=name;
    return 1;
  }

//! @decl int start_queue(string queue)
//! Start the queue @i{queue@} if not already printing.
//! @returns
//! Returns 0 if unable to connect, 1 otherwise. 
  int start_queue(string queue)
  {
    if(!queue) return 0;

    if(!connect(host, port))
      return 0;

    conn->write(sprintf("%c%s\n", 01, queue));
    string resp= conn->read();
    conn->close();
    return 1;
  }

//! @decl string|int send_job(string queue, string job)
//! Send print job consisting of data @i{job@} to printer @i{queue@}.
//! @returns
//! Returns 1 if success, 0 otherwise.
  int send_job(string queue, string job)
  {
    string resp;

    if(!queue) return 0;

    if(!connect(host, port))
      return 0;
    // werror("connected to " + host + "\n");

    string control="";
    control+="H"+gethostname()+"\n";
#if constant(getuid) && constant(getpwuid)
    control+="P"+(getpwuid(getuid())[0]||"nobody")+"\n";
#else
    control+="P-1\n";
#endif
    control+=(jobtype||"l")+"dfA"+ sprintf("%03d%s", jobnum, gethostname())+"\n";
    if(jobname)
    {
      control+="J" + jobname + "\n";
      control+="N" + jobname + "\n";
    }
    else
    { 
      control+="JPike LPD Client Job " + jobnum + "\n";
      control+="NPike LPD Client Job " + jobnum + "\n";
    }
    jobnum++;
werror("job file:\n\n" + control  + "\n\n");

    conn->write(sprintf("%c%s\n", 02, queue));
    resp=conn->read(1);
    if((int)resp !=0)
    {
      werror("receive job failed.\n");
      return 0;
    }

    conn->write(sprintf("%c%s cfA%03d%s\n", 02, (string)sizeof(control),
			jobnum,gethostname()));

    resp=conn->read(1);
    if((int)resp !=0)
    {
      werror("request receive control failed.\n");
      return 0;
    }

    conn->write(sprintf("%s%c", control, 0));

    resp=conn->read(1);
    if((int)resp !=0)
    {
      werror("send receive control failed.\n");
      return 0;
    }

    conn->write(sprintf("%c%s dfA%03d%s\n", 03, (string)sizeof(job), jobnum,
			gethostname()));
    resp=conn->read(1);
    if((int)resp !=0)
    {
      werror("request receive job failed.\n");
      return 0;
    }


    conn->write(sprintf("%s%c", job, 0));

    resp=conn->read(1);
    if((int)resp !=0)
    {
      werror("send receive job failed.\n");
      return 0;
    }



    // read the response. 

//    resp=conn->read();
    if((int)(resp)!=0) 
    { 
      conn->close();
      return 0;
    }
    conn->close();
//    start_queue(queue);
    return 1;
  }

//! @decl int delete_job(string queue, int|void job)
//! Delete job @i{job@} from printer @i{queue@}.
//! @returns
//! Returns 1 on success, 0 otherwise.
  int delete_job(string queue, int|void job)
  {
    if(!queue) return 0;

    if(!connect(host, port))
      return 0;

#if constant(getpwuid) && constant(getuid)
    string agent=(getpwuid(getuid())[0]||"nobody");
#else
    string agent="nobody";
#endif

    if(job)
      conn->write(sprintf("%c%s %s %d\n", 05, queue, agent, job));
    else
      conn->write(sprintf("%c%s %s\n", 05, queue, agent));
    string resp= conn->read();
    conn->close();
    return 1;
  }


//! @decl string|int status(string queue)
//! Check the status of queue @i{queue@}.
//! @returns
//! Returns 0 on failure, otherwise returns the status response from the printer.
  string|int status(string queue)
  {
    if(!queue) return 0;

    if(!connect(host, port))
      return 0;

    conn->write(sprintf("%c%s\n", 04, queue));
    string resp= conn->read();
    conn->close();
    return resp;
  }

//! Create a new LPD client connection.
//! @param hostname
//! Contains the hostname or ipaddress of the print host.
//! if not provided, defaults to @i{localhost@}.
//! @param portnum
//! Contains the port the print host is listening on.
//! if not provided, defaults to port @i{515@}, the RFC 1179 standard.
  void create(string|void hostname, int|void portnum)
  {
    host=hostname || "localhost";
    port=portnum || 515;
    conn=Stdio.File();
    jobnum=1;
  }
}