PX : code

LPHPRng: PHP Interfa by John Callaghan
Download this code


<!-
 This page was generated, in part, with lprng.php3. 
     http://www.msu.edu/user/callagh4/lprng/

 LPHPRng: LPRng PHP-3.0 Script (lprng.php3, v 1.0) (c) 1998-1999
      Michigan State University Board of Trustees.  All rights reserved.
  ->

<?

/*

LPHPRng: LPRng PHP-3.0 Script (lprng.php3, v 1.0) (c) 1998-1999
     Michigan State University Board of Trustees.  All rights reserved.

Author:       John Callaghan callagh4@msu.edu
Package:      lprng.php3, version 1.0 April 1999
Distribution: http://www.msu.edu/user/callagh4/lprng/
Thank-yous:   Regents of the University of California for the use of your 
              license agreement and disclaimer.  The PHP folks for PHP3
              (http://www.php.net/).  Patrick Powell and AStArt Technologies
              for LPRng (http://www.astart.com/LPRng.html).

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

3. All advertising materials mentioning features or use of this software
   must display the following acknowledgement:
      This product includes software developed by Michigan State University.

4. Neither the name of the University nor the names of its contributors
   may be used to endorse or promote products derived from this software
   without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY MICHIGAN STATE UNIVERSITY `` AS IS '' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE     
DISCLAIMED.  IN NO EVENT SHALL MICHIGAN STATE UNIVERSITY BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR        
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
SUCH DAMAGE.                                                              

*/

/********************************/
/*                              */
/* Some global values.          */
/*                              */
/********************************/

/* Examples:
$LP_username = getenv("REMOTE_USER");
$LP_username = 'george';
*/

$LP_username = "web";
$LP_port     = 515;

/********************************/
/*                              */
/* These globals get set by the */
/* functions.                   */
/*        $LP_errno             */
/*        $LP_errorarray        */
/*        $LP_errstr            */
/*                              */
/* So far they are not very     */
/* useful, perhaps some day.    */
/*                              */
/********************************/

/********************************/
/*                              */
/* Send the lpr request string  */
/* to the specified host.  Then */
/* get the response and stuff   */
/* it into an array.            */
/*                              */
/* Each line is trimmed,        */
/* removing white space from    */
/* both ends.                   */
/*                              */
/********************************/

function lp_fetch($hostname, $lpstr)
{
global $LP_port;
global $LP_errno;
global $LP_errstr;

@unset($LP_errno);
@unset($LP_errstr);
@unset($retarray);

$linelen = 1024;

/********************************/
/*                              */
/* Check the dns entry for the  */
/* hostname.  This is simply to */
/* give better feed back as to  */
/* any errors.                  */
/*                              */
/********************************/

if(!checkdnsrr($hostname, "A"))
    {
    $LP_errno = 1;
    $LP_errstr = "Host '$hostname' not found";
    return;
    }

/********************************/
/*                              */
/* Open a socket to the print   */
/* server.                      */
/*                              */
/********************************/

$sock = fsockopen($hostname, $LP_port, $LP_errno, $LP_errstr);
if(!$sock) return;

fwrite($sock, $lpstr);

/********************************/
/*                              */
/* Slurp up the whole response. */
/*                              */
/********************************/

for($string = fgets($sock, $linelen); $string; $string = fgets($sock, $linelen))
    {
    $retarray[] = trim($string);
    }

fclose($sock);

return $retarray;
}

/********************************/
/*                              */
/* Parses the queue info        */
/* returned by the server.      */
/*                              */
/* I release the returned array */
/* is really ugly, perhaps I'll */
/* fix things up in another     */
/* version.                     */
/*                              */
/********************************/

/*

From LPQ's printer line:
    $retarray[$pserver][$printer]["comment"] = $comment;
    $retarray[$pserver][$printer]["destination"] = $destination;
    $retarray[$pserver][$printer]["subservers"][] = $subserv;
    $retarray[$pserver][$printer]["server"] = $server;

From LPQ's job lines:
    $retarray[$pserver][$printer]["jobs"][]       = $lpqline;
        $lpqline = array("printer"  => $printer,
                         "pserver"  => $pserver,
                         "source"   => $source,
                         "rank"     => $rank,
                         "owner"    => $owner,
                         "username" => $username,
                         "source"   => $source,
                         "class"    => $class,
                         "jobid"    => $jobid,
                         "file"     => $filename,
                         "size"     => $size,
                         "time"     => $time);

From LPQ's other lines (Prefix: text):
    $retarray[$pserver][$printer]['status'][]           = $text;
    $retarray[$pserver][$printer][str_tolower($prefix)] = $text;

*/

function lpq($printserver = "localhost", $printer = "all", $options = "")
{
@unset($retarray);

/********************************/
/*                              */
/* Check out our arguments.     */
/*                              */
/********************************/

if(!is_array($options)) $options = array($options);

/* \4printername option option\n */

$outstr = "\4" . $printer . " " . implode($options, " ") . "\n";

/********************************/
/*                              */
/* Get the server's response.   */
/*                              */
/********************************/

$rawarray = lp_fetch($printserver, $outstr);
if(!is_array($rawarray)) return $retarray;

/********************************/
/*                              */
/* Some strings we will use.    */
/*                              */
/********************************/

$rankstring    = "Rank";
$printerstring = "Printer:";
$errorstring   = "ERROR:";
$serverstring  = "Server";
$statusstring  = "Status:";

$injobs = 0;

/********************************/
/*                              */
/* Go through the array.        */
/*                              */
/********************************/

reset($rawarray);
while(list($key, $string) = each($rawarray))
    {
    if(strlen($string) == 0) continue;

/********************************/
/*                              */
/* What is the first word of    */
/* the current line.            */
/*                              */
/********************************/

    $firsttoken = strtok($string, " ");

/********************************/
/*                              */
/* If the first token is        */
/* Printer: or Server, then     */
/* we have the printer info     */
/* line.                        */
/*                              */
/* Form:                        */
/*   [Server ]Printer:        \ */
/*    Q@PRINTSERVER           \ */
/*    (dest Q@PRINTSERVER)    \ */
/*    [(serving Q1)|          \ */
/*     (subservers Q1, ...)]  \ */
/*    ... 'COMMENT'             */
/*                              */
/********************************/

    if($firsttoken == $printerstring  || $firsttoken == $serverstring)
        {
        $injobs = 0;

        if($firsttoken == $serverstring) $secondtoken = strtok(" ");

/********************************/
/*                              */
/* Get the queuename, print     */
/* server and option comment.   */
/*                              */
/********************************/

        if(ereg(":[ ]+([^@]+)@([^ ]+)[^']+('([^']+)')?", $string, $regexarray))
            {
            $printer = $regexarray[1];
            $pserver = $regexarray[2];
            $comment = $regexarray[4];

            $retarray[$pserver][$printer]["comment"] = $comment;
            }

/********************************/
/*                              */
/* Does it have a destination   */
/* listed?                      */
/*                              */
/********************************/

        if(ereg("\(dest([^\)]+)\)", $string, $regexarray))
            {
            $destination = $regexarray[1];

            $retarray[$pserver][$printer]["destination"] = $destination;
            }

/********************************/
/*                              */
/* Is is a server queue?        */
/*                              */
/********************************/

        if(ereg("\(subservers([^\)]+)\)", $string, $regexarray))
            {
            $subserver = $regexarray[1];

            $subserverarray = split("[ ]+|[,]|[)]", $subserver);

            @reset($subserverarray);
            while(list($index, $subserv) = @each($subserverarray))
                {
                if(strlen($subserv) == 0) continue;

                $retarray[$pserver][$printer]["subservers"][] = $subserv;
                }
            }

/********************************/
/*                              */
/* Is it a subserver queue?     */
/*                              */
/********************************/

        if(ereg("\(serving([^\)]+)\)", $string, $regexarray))
            {
            $serving = $regexarray[1];

            $retarray[$pserver][$printer]["server"] = trim($serving);
            }

        continue;
        }

/********************************/
/*                              */
/* '^Rank' indicates we are     */
/* getting to the job list.     */
/*                              */
/*                              */
/********************************/

    if($firsttoken == $rankstring)
        {
        $injobs = 1;

        continue;
        }

/********************************/
/*                              */
/* Finally the jobs listing.    */
/*                              */
/********************************/

    switch($injobs)
        {
        case 1:
            {
            if(!eregi("([^ ]+)[ ]+" .                         // Rank
                      "([^@]+)@([^\+]+)\+([0-9]+)[ ]+" .     // Owner
                      "([a-z])[ ]+" .                         // Class
                      "[0-9]*[ ]*" .             // Jobid (not always complete)
                      "(.*)[ ]+" .               // Filename (not always there)
                      "([0-9]+)[ ]+" .                        // Size
                      "(([0-9]{4}-[0-9]{1,2}-[0-9]{1,2}-)?" . // Time
                      "[0-9]+:[0-9]+:[0-9]+)",                // Date
                      $string, $regexarray))
                {
                continue;
                }

            $rank     = $regexarray[1];
            $username = $regexarray[2];
            $source   = $regexarray[3];
            $jobid    = $regexarray[4];
            $owner    = "$username@$pserver+$jobid";
            $class    = $regexarray[5];
            $filename = $regexarray[6];
            $size     = $regexarray[7];
            $time     = $regexarray[8];

            if(strlen($filename) == 0) $filename = "unknown";

            $lpqline = array("printer"  => $printer,
                             "pserver"  => $pserver,
                             "source"   => $source,
                             "rank"     => $rank,
                             "owner"    => $owner,
                             "username" => $username,
                             "source"   => $source,
                             "class"    => $class,
                             "jobid"    => $jobid,
                             "file"     => $filename,
                             "size"     => $size,
                             "time"     => $time);

            $retarray[$pserver][$printer]["jobs"][] = $lpqline;

            break;
            }

/********************************/
/*                              */
/* Some other token starts      */
/* the line, like Error, Status,*/
/* etc.                         */
/*                              */
/********************************/

        default:
            {
            $lctoken = strtolower(strtok($string, ":"));
            $value   = strtok("");

            if(strlen(strstr($value, "no permission")) != 0)
                {
                $value   = $string;
                $lctoken = "error";
                }

            if($lctoken == "status")
                {
                $retarray[$pserver][$printer][$lctoken][] = $value;
                }
            else
                {
                $retarray[$pserver][$printer][$lctoken]   = $value;
                }

            break;
            }
        }
    }

@reset($retarray);
return $retarray;
}

/********************************/
/*                              */
/* Removing jobs.               */
/*                              */
/********************************/

function lprm($printserver, $printer, $args = "", $raw = 0)
{
global $LP_errorarray;
global $LP_username;

@unset($LP_errorarray);
@unset($retarray);

if(!is_array($args)) $args = array($args);
if(strlen(@trim($printer))     == 0) $printer = "all";

/* \5printername username option option\n */

$outstr = "\5$printer $LP_username " . implode($args, " ") . "\n";

$lprmarray = lp_fetch($printserver, $outstr);

/********************************/
/*                              */
/* If they want it raw, then    */
/* don't process the output.    */
/*                              */
/********************************/

if($raw) return $lprmarray;

for($count = 0; $count < @count($lprmarray); $count++)
    {
    $string = strtok($lprmarray[$count], " ");

/********************************/
/*                              */
/* What queue are we talking    */
/* about?                       */
/*                              */
/********************************/

    if($string == "Printer")
        {
        $printer = strtok("@");
        $pserver = strtok(":");

        continue;
        }

/********************************/
/*                              */
/* We only understand two types */
/* of lines.                    */
/*                              */
/********************************/

    if($string != "dequeued")
        {
        $LP_errorarray[] = $lprmarray[$count];

        continue;
        }

/********************************/
/*                              */
/* Break apart a 'dequeued'     */
/* line.  It is of the form:    */
/*  dequeued user@printhost+id  */
/*                              */
/********************************/

    $retval = ereg("'([^@]*)@([^+]*)\+([^']*)'", $lprmarray[$count], $array);

    if($retval == 0)
        {
        $LP_errorarray[] = $lprmarray[$count];

        continue;
        }

    $retarray[] = array("username" => $array[1],
                        "source"   => $array[2],
                        "jobid"    => $array[3],
                        "pserver"  => $pserver,
                        "printer"  => $printer);
    }

return $retarray;
}

/********************************/
/*                              */
/* Execute any lpc command.     */
/*                              */
/********************************/

function lpc($printserver, $printer, $args = "")
{
global $LP_username;

@unset($retarray);

if(!is_array($args)) $args = array($args);

if(strlen(@trim($printer))     == 0) $printer = "all";

/* \6printer user function options */

$outstr = "\6$printer $LP_username " . implode($args, " ") . "\n";

$retarray = lp_fetch($printserver, $outstr);

return $retarray;
}

/********************************/
/*                              */
/* Execute and process lpc's    */
/* status command.              */
/*                              */
/********************************/

function lp_status($printserver = "localhost", $printer = "all")
{
global $LP_username;
global $LP_errorarray;

@unset($LP_errorarray);
@unset($retarray);

/********************************/
/*                              */
/* Get the status of all        */
/* printers if the printer      */
/* string is empty.             */
/*                              */
/********************************/

if(strlen(@trim($printer))     == 0) $printer = "all";

/********************************/
/*                              */
/* Where do we find what we     */
/* need?                        */
/*                              */
/********************************/

$printingindex = 1;
$spoolingindex = 2;
$jobsindex     = 3;
$serverindex   = 4;
$slaveindex    = 5;
$redirectindex = 6;
$statusindex   = 7;

/********************************/
/*                              */
/* Issue the status command of  */
/* lpc.                         */
/*                              */
/********************************/

$rawarray = lpc($printserver, $printer, array("status"));

/********************************/
/*                              */
/* Skip the first line, it is   */
/* simply column headers.       */
/*                              */
/********************************/

@reset($rawarray);
@next($rawarray);

/********************************/
/*                              */
/* Go through the raw lpc array.*/
/*                              */
/********************************/

while(list($index, $line) = @each($rawarray))
    {
    if(strlen(strstr($line, "not in printcap")) != 0)
        {
        $LP_errorarray[] = $line;
        continue;
        }

/********************************/
/*                              */
/* Break on white space.        */
/*                              */
/********************************/

    $array = split(" +", $line);

    list($printer, $pserver) = explode("@", $array[0]);

/********************************/
/*                              */
/* Sanity check!  Make sure we  */
/* recognize the printing and   */
/* spooling columns.            */
/*                              */
/********************************/

    if($array[$printingindex] != "enabled"  &&
       $array[$printingindex] != "disabled" &&
       $array[$printingindex] != "aborted"  &&
       $array[$spoolingindex] != "enabled"  &&
       $array[$spoolingindex] != "disabled")
        {
        $LP_errorarray[] = $line;
        continue;
        }

/********************************/
/*                              */
/* If there is a status column  */
/* and no redirection, then     */
/* we will wrongly interpret    */
/* the status as the redirect.  */
/*                              */
/********************************/

    if(strstr($array[$redirectindex], '('))
        {
        $array[$statusindex] = $array[$redirectindex];
        $array[$redirectindex] = "";
        }

/********************************/
/*                              */
/* Add an entry to the return   */
/* array.                       */
/*                              */
/********************************/

    $retarray[$printer] = array("printer"  => $printer,
                                "pserver"  => $pserver,
                                "printing" => $array[$printingindex],
                                "spooling" => $array[$spoolingindex],
                                "jobs"     => $array[$jobsindex],
                                "server"   => $array[$serverindex],
                                "slave"    => $array[$slaveindex],
                                "redirect" => $array[$redirectindex],
                                "status"   => $array[$statusindex]);
    }

return $retarray;
}

/********************************/
/*                              */
/* Get a list of printers.      */
/*                              */
/********************************/

function lp_getprinters($pserver = "localhost")
{
global $LP_username;

$statarray = lp_status($pserver, "all", $LP_username);

@reset($statarray);

while(list($index, $statline) = @each($statarray))
    {
    $retarray[] = $statline["printer"];
    }

@reset($retarray);

return $retarray;
}

/********************************/
/*                              */
/* Get a list of subservers.    */
/*                              */
/* Return array is like:        */
/*                              */
/* $retarray[server-queue] =    */
/*   array(sub1, sub2, ...);    */
/*                              */
/********************************/

function lp_getsubservers($pserver = "localhost", $printer = "all")
{
global $LP_username;

$retarray = array();

/********************************/
/*                              */
/* Get the short lpq format.    */
/*                              */
/********************************/

$rawarray = lp_fetch($pserver, "\3$printer $LP_username\n");

if(!is_array($rawarray)) return $retarray;

$pservershort = strtok($pserver, ".");

/********************************/
/*                              */
/* Go through the lpq array.    */
/*                              */
/********************************/

while(list($index, $lpqline) = each($rawarray))
    {
    if(strlen(strstr($lpqline, "(serving")) != 0) continue;

    if(!ereg("^(.+)@$pservershort", $lpqline, $regexarray)) continue;

    $printer = $regexarray[1];

/********************************/
/*                              */
/* Does the current queue have  */
/* subservers?                  */
/*                              */
/********************************/

    if(!ereg("\(subservers(.+)\)", $lpqline, $regexarray))
        {
        $retarray[$printer] = array();

        continue;
        }

    $subserverstr = $regexarray[1];

    $subserverarray = split("[ ]+|[,]|[)]", $subserverstr);

    while(list($index, $subserver) = @each($subserverarray))
        {
        if(strlen($subserver) == 0) continue;

        $retarray[$printer][] = $subserver;
        }
    }

@reset($retarray);

return $retarray;
}

/********************************/
/*                              */
/* Parse LPRng's different time */
/* formats.                     */
/*                              */
/********************************/

function lp_parsetime($lprngtimestr)
{

/********************************/
/*                              */
/* Get the current date/time    */
/* for default values.          */
/*                              */
/********************************/

$datearray = getdate(time());

/********************************/
/*                              */
/* The time format is:          */
/*     [YYYY-MM-DD-]HH:MM:SS    */
/*                              */
/********************************/

$array = explode("-", $lprngtimestr);

if(count($array) == 4)
    {
    $datearray["year"] = $array[0];
    $datearray["mon"]  = $array[1];
    $datearray["mday"] = $array[2];

    $timestr = $array[3];
    }
else
    {
    $timestr = $array[0];
    }

$array = explode(":", $timestr);

$datearray["hours"]   = $array[0];
$datearray["minutes"] = $array[1];
$datearray["seconds"] = $array[2];

/********************************/
/*                              */
/* Convert it to the number of  */
/* seconds since the epoch.     */
/*                              */
/********************************/

$time = mktime($datearray["hours"],   $datearray["minutes"],
               $datearray["seconds"], $datearray["mon"],
               $datearray["mday"],    $datearray["year"]);

return $time;
}

?>

Comments or questions?
PX is running PHP 5.2.17
Thanks to Miranda Productions for hosting and bandwidth.
Use of any code from PX is at your own risk.