If signing starts successfully, don't just turn it off automatically if
[jra/samba/.git] / source3 / printing / lpq_parse.c
index 42da593c8dfa1e5a4c84b9c6194732159542f206..111617e3aed5ced8ddf870fc458a6e8987bf9be1 100644 (file)
@@ -1,6 +1,5 @@
 /* 
-   Unix SMB/Netbios implementation.
-   Version 3.0
+   Unix SMB/CIFS implementation.
    lpq parsing routines
    Copyright (C) Andrew Tridgell 2000
    
 */
 
 #include "includes.h"
-extern int DEBUGLEVEL;
 
-
-static char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+static const char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                              "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err"};
 
 
@@ -129,6 +126,7 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
   }
 #endif /* OSF1 */
 
+  /* FIXME: Use next_token rather than strtok! */
   tok[0] = strtok(line2," \t");
   count++;
 
@@ -147,25 +145,21 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
   buf->size = atoi(tok[TOTALTOK]);
   buf->status = strequal(tok[RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED;
   buf->time = time(NULL);
-  StrnCpy(buf->user,tok[USERTOK],sizeof(buf->user)-1);
-  StrnCpy(buf->file,tok[FILETOK],sizeof(buf->file)-1);
+  fstrcpy(buf->fs_user,tok[USERTOK]);
+  fstrcpy(buf->fs_file,tok[FILETOK]);
 
   if ((FILETOK + 1) != TOTALTOK) {
-    int bufsize;
     int i;
 
-    bufsize = sizeof(buf->file) - strlen(buf->file) - 1;
-
     for (i = (FILETOK + 1); i < TOTALTOK; i++) {
-      safe_strcat(buf->file," ",bufsize);
-      safe_strcat(buf->file,tok[i],bufsize - 1);
-      bufsize = sizeof(buf->file) - strlen(buf->file) - 1;
-      if (bufsize <= 0) {
-        break;
-      }
+        /* FIXME: Using fstrcat rather than other means is a bit
+         * inefficient; this might be a problem for enormous queues with
+         * many fields. */
+         fstrcat(buf->fs_file, " ");
+         fstrcat(buf->fs_file, tok[i]);
     }
     /* Ensure null termination. */
-    buf->file[sizeof(buf->file)-1] = '\0';
+    fstrterminate(buf->fs_file);
   }
 
 #ifdef PRIOTOK
@@ -183,20 +177,39 @@ the lpq output.  The lpq time looks like "23:15:07"
 
 <allan@umich.edu> June 30, 1998.
 Modified to work with the re-written parse_lpq_lprng routine.
+
+<J.P.M.v.Itegem@tue.nl> Dec 17,1999
+Modified to work with lprng 3.16
+With lprng 3.16 The lpq time looks like
+                       "23:15:07"
+                       "23:15:07.100"
+                       "1999-12-16-23:15:07"
+                       "1999-12-16-23:15:07.100"
+
 */
 static time_t LPRng_time(char *time_string)
 {
-  time_t jobtime;
-  struct tm *t;
-
-  jobtime = time(NULL);         /* default case: take current time */
-  t = localtime(&jobtime);
-  t->tm_hour = atoi(time_string);
-  t->tm_min = atoi(time_string+3);
-  t->tm_sec = atoi(time_string+6);
-  jobtime = mktime(t);
-
-  return jobtime;
+       time_t jobtime;
+       struct tm t;
+
+       jobtime = time(NULL);         /* default case: take current time */
+       t = *localtime(&jobtime);
+
+       if ( atoi(time_string) < 24 ){
+               t.tm_hour = atoi(time_string);
+               t.tm_min = atoi(time_string+3);
+               t.tm_sec = atoi(time_string+6);
+       } else {
+               t.tm_year = atoi(time_string)-1900;
+               t.tm_mon = atoi(time_string+5)-1;
+               t.tm_mday = atoi(time_string+8);
+               t.tm_hour = atoi(time_string+11);
+               t.tm_min = atoi(time_string+14);
+               t.tm_sec = atoi(time_string+17);
+       }    
+       jobtime = mktime(&t);
+
+       return jobtime;
 }
 
 
@@ -218,18 +231,14 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
 #define        LPRNG_NTOK      7
 #define        LPRNG_MAXTOK    128 /* PFMA just to keep us from running away. */
 
-  char *tokarr[LPRNG_MAXTOK];
-  char *cptr;
+  fstring tokarr[LPRNG_MAXTOK];
+  const char *cptr;
+  char *ptr;
   int  num_tok = 0;
-  pstring line2;
 
-  pstrcpy(line2,line);
-  tokarr[0] = strtok(line2," \t");
-  num_tok++;
-  while (((tokarr[num_tok] = strtok(NULL," \t")) != NULL)
-         && (num_tok < LPRNG_MAXTOK)) {
+  cptr = line;
+  while(next_token( &cptr, tokarr[num_tok], " \t", sizeof(fstring)) && (num_tok < LPRNG_MAXTOK))
     num_tok++;
-  }
 
   /* We must get at least LPRNG_NTOK tokens. */
   if (num_tok < LPRNG_NTOK) {
@@ -245,6 +254,8 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
 
   if (strequal(tokarr[LPRNG_RANKTOK],"active")) {
     buf->status = LPQ_PRINTING;
+  } else if (strequal(tokarr[LPRNG_RANKTOK],"done")) {
+    buf->status = LPQ_PRINTED;
   } else if (isdigit((int)*tokarr[LPRNG_RANKTOK])) {
     buf->status = LPQ_QUEUED;
   } else {
@@ -255,34 +266,30 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
 
   buf->time = LPRng_time(tokarr[LPRNG_TIMETOK]);
 
-  StrnCpy(buf->user,tokarr[LPRNG_USERTOK],sizeof(buf->user)-1);
+  fstrcpy(buf->fs_user,tokarr[LPRNG_USERTOK]);
 
   /* The '@hostname' prevents windows from displaying the printing icon
    * for the current user on the taskbar.  Plop in a null.
    */
 
-  if ((cptr = strchr(buf->user,'@')) != NULL) {
-    *cptr = '\0';
+  if ((ptr = strchr_m(buf->fs_user,'@')) != NULL) {
+    *ptr = '\0';
   }
 
-  StrnCpy(buf->file,tokarr[LPRNG_FILETOK],sizeof(buf->file)-1);
+  fstrcpy(buf->fs_file,tokarr[LPRNG_FILETOK]);
 
   if ((LPRNG_FILETOK + 1) != LPRNG_TOTALTOK) {
-    int bufsize;
     int i;
 
-    bufsize = sizeof(buf->file) - strlen(buf->file) - 1;
-
     for (i = (LPRNG_FILETOK + 1); i < LPRNG_TOTALTOK; i++) {
-      safe_strcat(buf->file," ",bufsize);
-      safe_strcat(buf->file,tokarr[i],bufsize - 1);
-      bufsize = sizeof(buf->file) - strlen(buf->file) - 1;
-      if (bufsize <= 0) {
-        break;
-      }
+      /* FIXME: Using fstrcat rather than other means is a bit
+       * inefficient; this might be a problem for enormous queues with
+       * many fields. */
+      fstrcat(buf->fs_file, " ");
+      fstrcat(buf->fs_file, tokarr[i]);
     }
     /* Ensure null termination. */
-    buf->file[sizeof(buf->file)-1] = '\0';
+    fstrterminate(buf->fs_file);
   }
 
   return(True);
@@ -306,15 +313,16 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
 {
   fstring tok[11];
   int count=0;
+  const char *cline = line;
 
   /* handle the case of "(standard input)" as a filename */
-  pstring_sub(line,"standard input","STDIN");
+  string_sub(line,"standard input","STDIN",0);
   all_string_sub(line,"(","\"",0);
   all_string_sub(line,")","\"",0);
 
   for (count=0; 
        count<10 && 
-              next_token(&line,tok[count],NULL, sizeof(tok[count])); 
+              next_token(&cline,tok[count],NULL, sizeof(tok[count])); 
        count++) ;
 
   /* we must get 6 tokens */
@@ -326,13 +334,13 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
           if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4])) return(False);
           buf->size = atoi(tok[4]) * 1024;
           /* if the fname contains a space then use STDIN */
-          if (strchr(tok[2],' '))
+          if (strchr_m(tok[2],' '))
             fstrcpy(tok[2],"STDIN");
 
           /* only take the last part of the filename */
           {
             fstring tmp;
-            char *p = strrchr(tok[2],'/');
+            char *p = strrchr_m(tok[2],'/');
             if (p)
               {
                 fstrcpy(tmp,p+1);
@@ -345,8 +353,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
           buf->status = strequal(tok[0],"HELD")?LPQ_PAUSED:LPQ_QUEUED;
          buf->priority = 0;
           buf->time = time(NULL);
-          StrnCpy(buf->user,tok[3],sizeof(buf->user)-1);
-          StrnCpy(buf->file,tok[2],sizeof(buf->file)-1);
+          fstrcpy(buf->fs_user,tok[3]);
+         fstrcpy(buf->fs_file,tok[2]);
       }
       else
       {
@@ -360,13 +368,13 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
       if (!isdigit((int)*tok[3]) || !isdigit((int)*tok[8])) return(False);
       buf->size = atoi(tok[8]) * 1024;
       /* if the fname contains a space then use STDIN */
-      if (strchr(tok[4],' '))
+      if (strchr_m(tok[4],' '))
         fstrcpy(tok[4],"STDIN");
 
       /* only take the last part of the filename */
       {
         fstring tmp;
-        char *p = strrchr(tok[4],'/');
+        char *p = strrchr_m(tok[4],'/');
         if (p)
           {
             fstrcpy(tmp,p+1);
@@ -379,8 +387,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
       buf->status = strequal(tok[2],"RUNNING")?LPQ_PRINTING:LPQ_QUEUED;
       buf->priority = 0;
       buf->time = time(NULL);
-      StrnCpy(buf->user,tok[5],sizeof(buf->user)-1);
-      StrnCpy(buf->file,tok[4],sizeof(buf->file)-1);
+      fstrcpy(buf->fs_user,tok[5]);
+      fstrcpy(buf->fs_file,tok[4]);
   }
 
 
@@ -398,7 +406,7 @@ ljplus-2153         user           priority 0  Jan 19 08:14 on ljplus
 ljplus-2154         user           priority 0  Jan 19 08:14 from client
       (standard input)                          7551 bytes
 ****************************************************************************/
-static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
+static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
 {
   /* must read two lines to process, therefore keep some values static */
   static BOOL header_line_ok=False, base_prio_reset=False;
@@ -410,9 +418,9 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
   /* to store minimum priority to print, lpstat command should be invoked
      with -p option first, to work */
   static int base_prio;
   int count;
   char htab = '\011';  
+  const char *cline = line;
   fstring tok[12];
 
   /* If a line begins with a horizontal TAB, it is a subline type */
@@ -425,11 +433,11 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
     }
     if (!header_line_ok) return (False); /* incorrect header line */
     /* handle the case of "(standard input)" as a filename */
-    pstring_sub(line,"standard input","STDIN");
+    string_sub(line,"standard input","STDIN",0);
     all_string_sub(line,"(","\"",0);
     all_string_sub(line,")","\"",0);
     
-    for (count=0; count<2 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
+    for (count=0; count<2 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
     /* we must get 2 tokens */
     if (count < 2) return(False);
     
@@ -437,18 +445,18 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
     if (!isdigit((int)*tok[1])) return(False);
     
     /* if the fname contains a space then use STDIN */
-    if (strchr(tok[0],' '))
+    if (strchr_m(tok[0],' '))
       fstrcpy(tok[0],"STDIN");
     
     buf->size = atoi(tok[1]);
-    StrnCpy(buf->file,tok[0],sizeof(buf->file)-1);
+    fstrcpy(buf->fs_file,tok[0]);
     
     /* fill things from header line */
     buf->time = jobtime;
     buf->job = jobid;
     buf->status = jobstat;
     buf->priority = jobprio;
-    StrnCpy(buf->user,jobuser,sizeof(buf->user)-1);
+    fstrcpy(buf->fs_user,jobuser);
     
     return(True);
   }
@@ -463,9 +471,9 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
     else if (base_prio) base_prio_reset=False;
     
     /* handle the dash in the job id */
-    pstring_sub(line,"-"," ");
+    string_sub(line,"-"," ",0);
     
-    for (count=0; count<12 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
+    for (count=0; count<12 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
       
     /* we must get 8 tokens */
     if (count < 8) return(False);
@@ -474,7 +482,7 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
     /* the 2nd, 5th & 7th column must be integer */
     if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4]) || !isdigit((int)*tok[6])) return(False);
     jobid = atoi(tok[1]);
-    StrnCpy(jobuser,tok[2],sizeof(buf->user)-1);
+    fstrcpy(jobuser,tok[2]);
     jobprio = atoi(tok[4]);
     
     /* process time */
@@ -511,6 +519,7 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
   fstring tok[9];
   int count=0;
   char *p;
+  const char *cline = line;
 
   /* 
    * Handle the dash in the job id, but make sure that we skip over
@@ -534,7 +543,7 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
   if((p >= line) && (*p == '-'))
     *p = ' ';
 
-  for (count=0; count<9 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++)
+  for (count=0; count<9 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++)
     ;
 
   /* we must get 7 tokens */
@@ -548,7 +557,7 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
     return(False);
 
   /* if the user contains a ! then trim the first part of it */  
-  if ((p=strchr(tok[2],'!'))) {
+  if ((p=strchr_m(tok[2],'!'))) {
       fstring tmp;
       fstrcpy(tmp,p+1);
       fstrcpy(tok[2],tmp);
@@ -564,8 +573,8 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
     buf->status = LPQ_QUEUED;
   buf->priority = 0;
   buf->time = EntryTime(tok, 4, count, 7);
-  StrnCpy(buf->user,tok[2],sizeof(buf->user)-1);
-  StrnCpy(buf->file,tok[2],sizeof(buf->file)-1);
+  fstrcpy(buf->fs_user,tok[2]);
+  fstrcpy(buf->fs_file,tok[2]);
   return(True);
 }
 
@@ -583,23 +592,22 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
 {
   fstring tok[7];
   int count=0;
+  const char *cline = line;
 
   DEBUG(4,("antes [%s]\n", line));
 
   /* handle the case of "-- standard input --" as a filename */
-  pstring_sub(line,"standard input","STDIN");
+  string_sub(line,"standard input","STDIN",0);
   DEBUG(4,("despues [%s]\n", line));
   all_string_sub(line,"-- ","\"",0);
   all_string_sub(line," --","\"",0);
   DEBUG(4,("despues 1 [%s]\n", line));
 
-  pstring_sub(line,"[job #","");
-  pstring_sub(line,"]","");
+  string_sub(line,"[job #","",0);
+  string_sub(line,"]","",0);
   DEBUG(4,("despues 2 [%s]\n", line));
 
-  
-  
-  for (count=0; count<7 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
+  for (count=0; count<7 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
 
   /* we must get 7 tokens */
   if (count < 7)
@@ -611,7 +619,7 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
   /* only take the last part of the filename */
   {
     fstring tmp;
-    char *p = strrchr(tok[6],'/');
+    char *p = strrchr_m(tok[6],'/');
     if (p)
       {
        fstrcpy(tmp,p+1);
@@ -625,8 +633,8 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
   buf->status = strequal(tok[3],"active")?LPQ_PRINTING:LPQ_QUEUED;
   buf->priority = 0;
   buf->time = time(NULL);
-  StrnCpy(buf->user,tok[1],sizeof(buf->user)-1);
-  StrnCpy(buf->file,tok[6],sizeof(buf->file)-1);
+  fstrcpy(buf->fs_user,tok[1]);
+  fstrcpy(buf->fs_file,tok[6]);
   return(True);
 }
 
@@ -648,13 +656,14 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
 {
   fstring tok[11];
   int count=0;
+  const char *cline = line;
 
   /* handle the case of "(standard input)" as a filename */
-  pstring_sub(line,"stdin","STDIN");
+  string_sub(line,"stdin","STDIN",0);
   all_string_sub(line,"(","\"",0);
   all_string_sub(line,")","\"",0);
   
-  for (count=0; count<11 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
+  for (count=0; count<11 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
 
   /* we must get 11 tokens */
   if (count < 11)
@@ -669,13 +678,13 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
     return(False);
 
   /* if the fname contains a space then use STDIN */
-  if (strchr(tok[6],' '))
+  if (strchr_m(tok[6],' '))
     fstrcpy(tok[6],"STDIN");
 
   /* only take the last part of the filename */
   {
     fstring tmp;
-    char *p = strrchr(tok[6],'/');
+    char *p = strrchr_m(tok[6],'/');
     if (p)
       {
         fstrcpy(tmp,p+1);
@@ -687,106 +696,231 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
   buf->job = atoi(tok[4]);
 
   buf->size = atoi(tok[7]);
-  if (strchr(tok[7],'K'))
+  if (strchr_m(tok[7],'K'))
     buf->size *= 1024;
-  if (strchr(tok[7],'M'))
+  if (strchr_m(tok[7],'M'))
     buf->size *= 1024*1024;
 
   buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED;
   buf->priority = 0;
   buf->time = time(NULL);
-  StrnCpy(buf->user,tok[1],sizeof(buf->user)-1);
-  StrnCpy(buf->file,tok[6],sizeof(buf->file)-1);
+  fstrcpy(buf->fs_user,tok[1]);
+  fstrcpy(buf->fs_file,tok[6]);
   return(True);
 }
 
-/****************************************************************************
-parse a qstat line
-
-here is an example of "qstat -l -d qms" output under softq
+/*******************************************************************
+parse lpq on an NT system
 
-Queue qms: 2 jobs; daemon active (313); enabled; accepting;
- job-ID   submission-time     pri     size owner      title 
-205980: H 98/03/09 13:04:05     0    15733 stephenf   chap1.ps
-206086:>  98/03/12 17:24:40     0      659 chris      -
-206087:   98/03/12 17:24:45     0     4876 chris      -
-Total:      21268 bytes in queue
+                         Windows 2000 LPD Server
+                              Printer \\10.0.0.2\NP17PCL (Paused)
 
+Owner       Status         Jobname          Job-Id    Size   Pages  Priority
+----------------------------------------------------------------------------
+root (9.99. Printing  /usr/lib/rhs/rhs-pr      3       625      0      1
+root (9.99. Paused    /usr/lib/rhs/rhs-pr      4       625      0      1
+jmcd        Waiting   Re: Samba Open Sour     26     32476      1      1
 
-****************************************************************************/
-static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first)
+********************************************************************/
+static BOOL parse_lpq_nt(char *line,print_queue_struct *buf,BOOL first)
 {
-  fstring tok[10];
-  int count=0;
+#define LPRNT_OWNSIZ 11
+#define LPRNT_STATSIZ 9
+#define LPRNT_JOBSIZ 19
+#define LPRNT_IDSIZ 6
+#define LPRNT_SIZSIZ 9
+  typedef struct 
+  {
+    char owner[LPRNT_OWNSIZ];
+    char space1;
+    char status[LPRNT_STATSIZ];
+    char space2;
+    char jobname[LPRNT_JOBSIZ];
+    char space3;
+    char jobid[LPRNT_IDSIZ];
+    char space4;
+    char size[LPRNT_SIZSIZ];
+    char terminator;
+  } nt_lpq_line;
+
+  nt_lpq_line parse_line;
+#define LPRNT_PRINTING "Printing"
+#define LPRNT_WAITING "Waiting"
+#define LPRNT_PAUSED "Paused"
+
+  memset(&parse_line, '\0', sizeof(parse_line));
+  strncpy((char *) &parse_line, line, sizeof(parse_line) -1);
+
+  if (strlen((char *) &parse_line) != sizeof(parse_line) - 1)
+    return(False);
 
-  /* mung all the ":"s to spaces*/
-  pstring_sub(line,":"," ");
-  
-  for (count=0; count<10 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
+  /* Just want the first word in the owner field - the username */
+  if (strchr_m(parse_line.owner, ' '))
+    *(strchr_m(parse_line.owner, ' ')) = '\0';
+  else
+    parse_line.space1 = '\0';
 
-  /* we must get 9 tokens */
-  if (count < 9)
+  /* Make sure we have an owner */
+  if (!strlen(parse_line.owner))
     return(False);
 
-  /* the 1st and 7th columns must be integer */
-  if (!isdigit((int)*tok[0]) || !isdigit((int)*tok[6]))  return(False);
-  /* if the 2nd column is either '>' or 'H' then the 7th and 8th must be
-   * integer, else it's the 6th and 7th that must be
-   */
-  if (*tok[1] == 'H' || *tok[1] == '>')
-    {
-      if (!isdigit((int)*tok[7]))
-        return(False);
-      buf->status = *tok[1] == '>' ? LPQ_PRINTING : LPQ_PAUSED;
-      count = 1;
-    }
+  /* Make sure the status is valid */
+  parse_line.space2 = '\0';
+  trim_char(parse_line.status, '\0', ' ');
+  if (!strequal(parse_line.status, LPRNT_PRINTING) &&
+      !strequal(parse_line.status, LPRNT_PAUSED) &&
+      !strequal(parse_line.status, LPRNT_WAITING))
+    return(False);
+  
+  parse_line.space3 = '\0';
+  trim_char(parse_line.jobname, '\0', ' ');
+
+  buf->job = atoi(parse_line.jobid);
+  buf->priority = 0;
+  buf->size = atoi(parse_line.size);
+  buf->time = time(NULL);
+  fstrcpy(buf->fs_user, parse_line.owner);
+  fstrcpy(buf->fs_file, parse_line.jobname);
+  if (strequal(parse_line.status, LPRNT_PRINTING))
+    buf->status = LPQ_PRINTING;
+  else if (strequal(parse_line.status, LPRNT_PAUSED))
+    buf->status = LPQ_PAUSED;
   else
-    {
-      if (!isdigit((int)*tok[5]))
-        return(False);
-      buf->status = LPQ_QUEUED;
-      count = 0;
-    }
-       
+    buf->status = LPQ_QUEUED;
+
+  return(True);
+}
+
+/*******************************************************************
+parse lpq on an OS2 system
+
+JobID  File Name          Rank      Size        Status          Comment       
+-----  ---------------    ------    --------    ------------    ------------  
+    3  Control                 1          68    Queued          root@psflinu  
+    4  /etc/motd               2       11666    Queued          root@psflinu  
 
-  buf->job = atoi(tok[0]);
-  buf->size = atoi(tok[count+6]);
-  buf->priority = atoi(tok[count+5]);
-  StrnCpy(buf->user,tok[count+7],sizeof(buf->user)-1);
-  StrnCpy(buf->file,tok[count+8],sizeof(buf->file)-1);
-  buf->time = time(NULL);              /* default case: take current time */
+********************************************************************/
+static BOOL parse_lpq_os2(char *line,print_queue_struct *buf,BOOL first)
+{
+#define LPROS2_IDSIZ 5
+#define LPROS2_JOBSIZ 15
+#define LPROS2_SIZSIZ 8
+#define LPROS2_STATSIZ 12
+#define LPROS2_OWNSIZ 12
+  typedef struct 
   {
-    time_t jobtime;
-    struct tm *t;
+    char jobid[LPROS2_IDSIZ];
+    char space1[2];
+    char jobname[LPROS2_JOBSIZ];
+    char space2[14];
+    char size[LPROS2_SIZSIZ];
+    char space3[4];
+    char status[LPROS2_STATSIZ];
+    char space4[4];
+    char owner[LPROS2_OWNSIZ];
+    char terminator;
+  } os2_lpq_line;
+
+  os2_lpq_line parse_line;
+#define LPROS2_PRINTING "Printing"
+#define LPROS2_WAITING "Queued"
+#define LPROS2_PAUSED "Paused"
+
+  memset(&parse_line, '\0', sizeof(parse_line));
+  strncpy((char *) &parse_line, line, sizeof(parse_line) -1);
+
+  if (strlen((char *) &parse_line) != sizeof(parse_line) - 1)
+    return(False);
 
-    t = localtime(&buf->time);
-    t->tm_mday = atoi(tok[count+2]+6);
-    t->tm_mon  = atoi(tok[count+2]+3);
-    switch (*tok[count+2])
-    {
-    case 7: case 8: case 9: t->tm_year = atoi(tok[count+2]); break;
-    default:                t->tm_year = atoi(tok[count+2]); break;
-    }
+  /* Get the jobid */
+  buf->job = atoi(parse_line.jobid);
 
-    t->tm_hour = atoi(tok[count+3]);
-    t->tm_min = atoi(tok[count+4]);
-    t->tm_sec = atoi(tok[count+5]);
-    jobtime = mktime(t);
-    if (jobtime != (time_t)-1)
-      buf->time = jobtime; 
-  }
+  /* Get the job name */
+  parse_line.space2[0] = '\0';
+  trim_char(parse_line.jobname, '\0', ' ');
+  fstrcpy(buf->fs_file, parse_line.jobname);
+
+  buf->priority = 0;
+  buf->size = atoi(parse_line.size);
+  buf->time = time(NULL);
+
+  /* Make sure we have an owner */
+  if (!strlen(parse_line.owner))
+    return(False);
+
+  /* Make sure we have a valid status */
+  parse_line.space4[0] = '\0';
+  trim_char(parse_line.status, '\0', ' ');
+  if (!strequal(parse_line.status, LPROS2_PRINTING) &&
+      !strequal(parse_line.status, LPROS2_PAUSED) &&
+      !strequal(parse_line.status, LPROS2_WAITING))
+    return(False);
+
+  fstrcpy(buf->fs_user, parse_line.owner);
+  if (strequal(parse_line.status, LPROS2_PRINTING))
+    buf->status = LPQ_PRINTING;
+  else if (strequal(parse_line.status, LPROS2_PAUSED))
+    buf->status = LPQ_PAUSED;
+  else
+    buf->status = LPQ_QUEUED;
 
   return(True);
 }
 
+static const char *stat0_strings[] = { "enabled", "online", "idle", "no entries", "free", "ready", NULL };
+static const char *stat1_strings[] = { "offline", "disabled", "down", "off", "waiting", "no daemon", NULL };
+static const char *stat2_strings[] = { "jam", "paper", "error", "responding", "not accepting", "not running", "turned off", NULL };
 
-static char *stat0_strings[] = { "enabled", "online", "idle", "no entries", "free", "ready", NULL };
-static char *stat1_strings[] = { "offline", "disabled", "down", "off", "waiting", "no daemon", NULL };
-static char *stat2_strings[] = { "jam", "paper", "error", "responding", "not accepting", "not running", "turned off", NULL };
+#ifdef DEVELOPER
+
+/****************************************************************************
+parse a vlp line
+****************************************************************************/
+static BOOL parse_lpq_vlp(char *line,print_queue_struct *buf,BOOL first)
+{
+       int toknum = 0;
+       fstring tok;
+       const char *cline = line;
+
+       /* First line is printer status */
+
+       if (!isdigit(line[0])) return False;
+
+       /* Parse a print job entry */
+
+       while(next_token(&cline, tok, NULL, sizeof(fstring))) {
+               switch (toknum) {
+               case 0:
+                       buf->job = atoi(tok);
+                       break;
+               case 1:
+                       buf->size = atoi(tok);
+                       break;
+               case 2:
+                       buf->status = atoi(tok);
+                       break;
+               case 3:
+                       buf->time = atoi(tok);
+                       break;
+               case 4:
+                       fstrcpy(buf->fs_user, tok);
+                       break;
+               case 5:
+                       fstrcpy(buf->fs_file, tok);
+                       break;
+               }
+               toknum++;
+       }
+
+       return True;
+}
+
+#endif /* DEVELOPER */
 
 /****************************************************************************
 parse a lpq line. Choose printing style
 ****************************************************************************/
+
 BOOL parse_lpq_entry(int snum,char *line,
                     print_queue_struct *buf,
                     print_status_struct *status,BOOL first)
@@ -813,9 +947,18 @@ BOOL parse_lpq_entry(int snum,char *line,
     case PRINT_PLP:
       ret = parse_lpq_plp(line,buf,first);
       break;
-    case PRINT_SOFTQ:
-      ret = parse_lpq_softq(line,buf,first);
+    case PRINT_LPRNT:
+      ret = parse_lpq_nt(line,buf,first);
+      break;
+    case PRINT_LPROS2:
+      ret = parse_lpq_os2(line,buf,first);
       break;
+#ifdef DEVELOPER
+    case PRINT_VLP:
+    case PRINT_TEST:
+           ret = parse_lpq_vlp(line,buf,first);
+           break;
+#endif /* DEVELOPER */
     default:
       ret = parse_lpq_bsd(line,buf,first);
       break;
@@ -823,7 +966,7 @@ BOOL parse_lpq_entry(int snum,char *line,
 
   /* We don't want the newline in the status message. */
   {
-    char *p = strchr(line,'\n');
+    char *p = strchr_m(line,'\n');
     if (p) *p = 0;
   }
 
@@ -841,29 +984,29 @@ BOOL parse_lpq_entry(int snum,char *line,
          printer status line: 
         handle them so that most severe condition is shown */
       int i;
-      strlower(line);
+      strlower_m(line);
       
       switch (status->status) {
       case LPSTAT_OK:
        for (i=0; stat0_strings[i]; i++)
          if (strstr(line,stat0_strings[i])) {
-           StrnCpy(status->message,line,sizeof(status->message)-1);
-           status->status=LPSTAT_OK;
-           return ret;
+                 fstrcpy(status->message,line);
+                 status->status=LPSTAT_OK;
+                 return ret;
          }
       case LPSTAT_STOPPED:
        for (i=0; stat1_strings[i]; i++)
          if (strstr(line,stat1_strings[i])) {
-           StrnCpy(status->message,line,sizeof(status->message)-1);
-           status->status=LPSTAT_STOPPED;
-           return ret;
+                 fstrcpy(status->message,line);
+                 status->status=LPSTAT_STOPPED;
+                 return ret;
          }
       case LPSTAT_ERROR:
        for (i=0; stat2_strings[i]; i++)
          if (strstr(line,stat2_strings[i])) {
-           StrnCpy(status->message,line,sizeof(status->message)-1);
-           status->status=LPSTAT_ERROR;
-           return ret;
+                 fstrcpy(status->message,line);
+                 status->status=LPSTAT_ERROR;
+                 return ret;
          }
        break;
       }