pike comment // pike comment // LPD.pmod: an implementation of the BSD lpd protocol (RFC 1179). pike comment // This is a module for pike. pike comment // 3 July 1998 Bill Welliver pike comment // pike comment // $Id: LPD.pmod,v 1.10 2008/01/13 17:02:43 nilsson Exp $ pike comment // pike blank pike code #pike __REAL_VERSION__ pike blank pike comment //! A client for communicating with printers and print spoolers that pike comment //! support the BSD lpd protocol (RFC 1179). pike code class client { pike code string host; pike code int port; pike code private object conn; pike code int jobnum; pike code string jobtype; pike code string jobname; pike blank pike code private int connect(string host, int port) pike code { pike code int a=random(10); pike comment // try to open one of the "official" local socket ports. pike comment // not having one doesn't seem to be a problem with most LPD pike comment // servers, but we should at least try. will probably fail pike comment // if two try to open the same local port at once. ymmv. pike code int res=conn->open_socket(721 + a); pike blank pike code return conn->connect(host, port); pike code } pike blank pike comment //! @decl int set_job_type(string type) pike comment //! Set the type of job to be sent to the printer to @i{type@}. pike comment //! Valid types are: text, postscript and raw. pike code int set_job_type(string type) pike code { pike code type=lower_case(type); pike blank pike code switch (type) { pike code case "f": pike code case "text": pike code jobtype="f"; pike code break; pike blank pike code case "o": pike code case "postscript": pike code case "ps": pike code jobtype="o"; pike code break; pike blank pike code default: pike code case "l": pike code case "raw": pike code jobtype="l"; pike code break; pike code } pike code return 1; pike code } pike blank pike comment //! @decl int set_job_name(string name) pike comment //! Sets the name of the print job to @i{name@}. pike code int set_job_name(string name) pike code { pike code jobname=name; pike code return 1; pike code } pike blank pike comment //! @decl int start_queue(string queue) pike comment //! Start the queue @i{queue@} if not already printing. pike comment //! @returns pike comment //! Returns 0 if unable to connect, 1 otherwise. pike code int start_queue(string queue) pike code { pike code if(!queue) return 0; pike blank pike code if(!connect(host, port)) pike code return 0; pike blank pike code conn->write(sprintf("%c%s\n", 01, queue)); pike code string resp= conn->read(); pike code conn->close(); pike code return 1; pike code } pike blank pike comment //! @decl string|int send_job(string queue, string job) pike comment //! Send print job consisting of data @i{job@} to printer @i{queue@}. pike comment //! @returns pike comment //! Returns 1 if success, 0 otherwise. pike code int send_job(string queue, string job) pike code { pike code string resp; pike blank pike code if(!queue) return 0; pike blank pike code if(!connect(host, port)) pike code return 0; pike comment // werror("connected to " + host + "\n"); pike blank pike code string control=""; pike code control+="H"+gethostname()+"\n"; pike code #if constant(getuid) && constant(getpwuid) pike code control+="P"+(getpwuid(getuid())[0]||"nobody")+"\n"; pike code #else pike code control+="P-1\n"; pike code #endif pike code control+=(jobtype||"l")+"dfA"+ sprintf("%03d%s", jobnum, gethostname())+"\n"; pike code if(jobname) pike code { pike code control+="J" + jobname + "\n"; pike code control+="N" + jobname + "\n"; pike code } pike code else pike code { pike code control+="JPike LPD Client Job " + jobnum + "\n"; pike code control+="NPike LPD Client Job " + jobnum + "\n"; pike code } pike code jobnum++; pike code werror("job file:\n\n" + control + "\n\n"); pike blank pike code conn->write(sprintf("%c%s\n", 02, queue)); pike code resp=conn->read(1); pike code if((int)resp !=0) pike code { pike code werror("receive job failed.\n"); pike code return 0; pike code } pike blank pike code conn->write(sprintf("%c%s cfA%03d%s\n", 02, (string)sizeof(control), pike code jobnum,gethostname())); pike blank pike code resp=conn->read(1); pike code if((int)resp !=0) pike code { pike code werror("request receive control failed.\n"); pike code return 0; pike code } pike blank pike code conn->write(sprintf("%s%c", control, 0)); pike blank pike code resp=conn->read(1); pike code if((int)resp !=0) pike code { pike code werror("send receive control failed.\n"); pike code return 0; pike code } pike blank pike code conn->write(sprintf("%c%s dfA%03d%s\n", 03, (string)sizeof(job), jobnum, pike code gethostname())); pike code resp=conn->read(1); pike code if((int)resp !=0) pike code { pike code werror("request receive job failed.\n"); pike code return 0; pike code } pike blank pike blank pike code conn->write(sprintf("%s%c", job, 0)); pike blank pike code resp=conn->read(1); pike code if((int)resp !=0) pike code { pike code werror("send receive job failed.\n"); pike code return 0; pike code } pike blank pike blank pike blank pike comment // read the response. pike blank pike comment // resp=conn->read(); pike code if((int)(resp)!=0) pike code { pike code conn->close(); pike code return 0; pike code } pike code conn->close(); pike comment // start_queue(queue); pike code return 1; pike code } pike blank pike comment //! @decl int delete_job(string queue, int|void job) pike comment //! Delete job @i{job@} from printer @i{queue@}. pike comment //! @returns pike comment //! Returns 1 on success, 0 otherwise. pike code int delete_job(string queue, int|void job) pike code { pike code if(!queue) return 0; pike blank pike code if(!connect(host, port)) pike code return 0; pike blank pike code #if constant(getpwuid) && constant(getuid) pike code string agent=(getpwuid(getuid())[0]||"nobody"); pike code #else pike code string agent="nobody"; pike code #endif pike blank pike code if(job) pike code conn->write(sprintf("%c%s %s %d\n", 05, queue, agent, job)); pike code else pike code conn->write(sprintf("%c%s %s\n", 05, queue, agent)); pike code string resp= conn->read(); pike code conn->close(); pike code return 1; pike code } pike blank pike blank pike comment //! @decl string|int status(string queue) pike comment //! Check the status of queue @i{queue@}. pike comment //! @returns pike comment //! Returns 0 on failure, otherwise returns the status response from the printer. pike code string|int status(string queue) pike code { pike code if(!queue) return 0; pike blank pike code if(!connect(host, port)) pike code return 0; pike blank pike code conn->write(sprintf("%c%s\n", 04, queue)); pike code string resp= conn->read(); pike code conn->close(); pike code return resp; pike code } pike blank pike comment //! Create a new LPD client connection. pike comment //! @param hostname pike comment //! Contains the hostname or ipaddress of the print host. pike comment //! if not provided, defaults to @i{localhost@}. pike comment //! @param portnum pike comment //! Contains the port the print host is listening on. pike comment //! if not provided, defaults to port @i{515@}, the RFC 1179 standard. pike code void create(string|void hostname, int|void portnum) pike code { pike code host=hostname || "localhost"; pike code port=portnum || 515; pike code conn=Stdio.File(); pike code jobnum=1; pike code } pike code } pike blank