fda9811998-04-03David Hedbor //
4505fe1998-07-03H. William Welliver III // LPD.pmod: an implementation of the BSD lpd protocol (RFC 1179).
fda9811998-04-03David Hedbor // This is a module for pike.
4505fe1998-07-03H. William Welliver III // 3 July 1998 <hww3@riverweb.com> Bill Welliver //
fda9811998-04-03David Hedbor 
a580e12000-09-27Fredrik Hübinette (Hubbe) #pike __REAL_VERSION__
a20af62000-09-26Fredrik Hübinette (Hubbe) 
f1e97a2002-06-14H. William Welliver III //! A client for communicating with printers and print spoolers that //! support the BSD lpd protocol (RFC 1179).
fda9811998-04-03David Hedbor class client { string host; int port;
f1e97a2002-06-14H. William Welliver III  private object conn;
fda9811998-04-03David Hedbor  int jobnum; string jobtype;
4505fe1998-07-03H. William Welliver III  string jobname;
fda9811998-04-03David Hedbor 
f1e97a2002-06-14H. William Welliver III  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.
fda9811998-04-03David Hedbor  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; }
f1e97a2002-06-14H. William Welliver III //! @decl int set_job_name(string name) //! Sets the name of the print job to @i{name@}.
4505fe1998-07-03H. William Welliver III  int set_job_name(string name) { jobname=name; return 1; }
f1e97a2002-06-14H. William Welliver III //! @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)
fda9811998-04-03David Hedbor  { if(!queue) return 0;
f1e97a2002-06-14H. William Welliver III  if(!connect(host, port))
fda9811998-04-03David Hedbor  return 0; conn->write(sprintf("%c%s\n", 01, queue)); string resp= conn->read(); conn->close(); return 1; }
f1e97a2002-06-14H. William Welliver III //! @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)
fda9811998-04-03David Hedbor  { string resp; if(!queue) return 0;
f1e97a2002-06-14H. William Welliver III  if(!connect(host, port))
fda9811998-04-03David Hedbor  return 0;
f1e97a2002-06-14H. William Welliver III  // werror("connected to " + host + "\n");
fda9811998-04-03David Hedbor  string control=""; control+="H"+gethostname()+"\n";
936efb1999-08-19Fredrik Hübinette (Hubbe) #if constant(getuid) && constant(getpwuid) control+="P"+(getpwuid(getuid())[0]||"nobody")+"\n"; #else
f1e97a2002-06-14H. William Welliver III  control+="P-1\n";
936efb1999-08-19Fredrik Hübinette (Hubbe) #endif
f1e97a2002-06-14H. William Welliver III  control+=(jobtype||"l")+"dfA"+ sprintf("%03d%s", jobnum, gethostname())+"\n";
4505fe1998-07-03H. William Welliver III  if(jobname)
f1e97a2002-06-14H. William Welliver III  {
4505fe1998-07-03H. William Welliver III  control+="J" + jobname + "\n";
f1e97a2002-06-14H. William Welliver III  control+="N" + jobname + "\n"; } else { control+="JPike LPD Client Job " + jobnum + "\n"; control+="NPike LPD Client Job " + jobnum + "\n"; }
fda9811998-04-03David Hedbor  jobnum++;
f1e97a2002-06-14H. William Welliver III 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),
fda9811998-04-03David Hedbor  jobnum,gethostname()));
f1e97a2002-06-14H. William Welliver III  resp=conn->read(1); if((int)resp !=0) { werror("request receive control failed.\n"); return 0; }
fda9811998-04-03David Hedbor  conn->write(sprintf("%s%c", control, 0));
f1e97a2002-06-14H. William Welliver III  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,
fda9811998-04-03David Hedbor  gethostname()));
f1e97a2002-06-14H. William Welliver III  resp=conn->read(1); if((int)resp !=0) { werror("request receive job failed.\n"); return 0; }
fda9811998-04-03David Hedbor  conn->write(sprintf("%s%c", job, 0));
f1e97a2002-06-14H. William Welliver III  resp=conn->read(1); if((int)resp !=0) { werror("send receive job failed.\n"); return 0; } // read the response.
fda9811998-04-03David Hedbor 
f1e97a2002-06-14H. William Welliver III // resp=conn->read(); if((int)(resp)!=0) { conn->close(); return 0; } conn->close(); // start_queue(queue);
fda9811998-04-03David Hedbor  return 1; }
f1e97a2002-06-14H. William Welliver III //! @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)
fda9811998-04-03David Hedbor  { if(!queue) return 0;
f1e97a2002-06-14H. William Welliver III  if(!connect(host, port))
fda9811998-04-03David Hedbor  return 0;
936efb1999-08-19Fredrik Hübinette (Hubbe) #if constant(getpwuid) && constant(getuid)
fda9811998-04-03David Hedbor  string agent=(getpwuid(getuid())[0]||"nobody");
936efb1999-08-19Fredrik Hübinette (Hubbe) #else string agent="nobody"; #endif
fda9811998-04-03David Hedbor  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; }
f1e97a2002-06-14H. William Welliver III //! @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.
fda9811998-04-03David Hedbor  string|int status(string queue) { if(!queue) return 0;
f1e97a2002-06-14H. William Welliver III  if(!connect(host, port))
fda9811998-04-03David Hedbor  return 0; conn->write(sprintf("%c%s\n", 04, queue)); string resp= conn->read(); conn->close(); return resp; }
f1e97a2002-06-14H. William Welliver III //! Create a new LPD client connection.
41d7d22002-06-17Martin Stjernholm //! @param hostname //! Contains the hostname or ipaddress of the print host.
f1e97a2002-06-14H. William Welliver III //! if not provided, defaults to @i{localhost@}.
41d7d22002-06-17Martin Stjernholm //! @param portnum
6af6912002-06-17Henrik Grubbström (Grubba) //! Contains the port the print host is listening on.
f1e97a2002-06-14H. William Welliver III //! if not provided, defaults to port @i{515@}, the RFC 1179 standard.
fda9811998-04-03David Hedbor  void create(string|void hostname, int|void portnum) { host=hostname || "localhost"; port=portnum || 515; conn=Stdio.File();
f1e97a2002-06-14H. William Welliver III  jobnum=1;
fda9811998-04-03David Hedbor  } }