Branch: Tag:

2002-06-14

2002-06-14 16:59:48 by H. William Welliver III <bill@welliver.org>

added autodoc documentation
added local port setting (attempts once, largely unnecessary part of rfc)
added response checking per spec.
sending jobs now works.

Rev: lib/modules/Protocols.pmod/LPD.pmod:1.7

3:   // This is a module for pike.   // 3 July 1998 <hww3@riverweb.com> Bill Welliver   // - // $Id: LPD.pmod,v 1.6 2000/09/28 03:38:50 hubbe Exp $ + // $Id: LPD.pmod,v 1.7 2002/06/14 16:59:48 bill 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; -  object conn; +  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);
41:    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;    }    -  string|int start_queue(string queue) + //! @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(!conn->connect(host, port)) +  if(!connect(host, port))    return 0;       conn->write(sprintf("%c%s\n", 01, queue));
60:    return 1;    }    -  string|int send_job(string queue, string job) + //! @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)    {    int r;    string resp;       if(!queue) return 0;    -  if(!conn->connect(host, port)) +  if(!connect(host, port))    return 0; -  werror("connected to " + host + "\n"); +  // werror("connected to " + host + "\n");    -  conn->write(sprintf("%c%s\n", 02, queue)); -  // werror("sent send data command\n"); +     string control="";    control+="H"+gethostname()+"\n";   #if constant(getuid) && constant(getpwuid)    control+="P"+(getpwuid(getuid())[0]||"nobody")+"\n";   #else -  /* Should there be a P-1 here? /Hubbe */ +  control+="P-1\n";   #endif -  control+=(jobtype||"l")+"dfA"+ sprintf("%3d%s", jobnum, gethostname())+"\n"; +  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++; -  conn->write(sprintf("%c%s cfA%3d%s\n", 02, (string)sizeof(control), + 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())); -  // werror("getting ready to send control file\n"); +     -  +  resp=conn->read(1); +  if((int)resp !=0) +  { +  werror("request receive control failed.\n"); +  return 0; +  } +     conn->write(sprintf("%s%c", control, 0)); -  // werror("sent control file\n"); +     -  conn->write(sprintf("%c%s dfA%3d%s\n", 03, (string)sizeof(job), jobnum, +  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)); -  // werror("sent data file\n"); +     -  conn->close(); -  start_queue(queue); +  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;    }    -  string|int delete_job(string queue, int|void job) + //! @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(!conn->connect(host, port)) +  if(!connect(host, port))    return 0;      #if constant(getpwuid) && constant(getuid)
125:    }       + //! @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(!conn->connect(host, port)) +  if(!connect(host, port))    return 0;       conn->write(sprintf("%c%s\n", 04, queue));
138:    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=0; +  jobnum=1;    }   }