Merge commit 'release-4-0-0alpha15' into master4-tmp
[amitay/samba.git] / source3 / printing / lpq_parse.c
index 5118429bd7c52e8fbdc39d121315798f72ebf6c1..9104497f9f663ff8813d068f08bd2a9116da9a74 100644 (file)
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
+#include "printing.h"
 
 static const char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                              "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err"};
@@ -28,7 +28,7 @@ static const char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  Process time fields
 ********************************************************************/
 
-static time_t EntryTime(fstring tok[], int ptr, int count, int minimum)
+static time_t EntryTime(char *tok[], int ptr, int count, int minimum)
 {
        time_t jobtime,jobtime1;
 
@@ -36,7 +36,6 @@ static time_t EntryTime(fstring tok[], int ptr, int count, int minimum)
        if (count >= minimum) {
                struct tm *t;
                int i, day, hour, min, sec;
-               char   *c;
 
                for (i=0; i<13; i++) {
                        if (!strncmp(tok[ptr], Months[i],3)) {
@@ -45,12 +44,13 @@ static time_t EntryTime(fstring tok[], int ptr, int count, int minimum)
                }
 
                if (i<12) {
+                       fstring c;
                        t = localtime(&jobtime);
                        if (!t) {
                                return (time_t)-1;
                        }
                        day = atoi(tok[ptr+1]);
-                       c=(char *)(tok[ptr+2]);
+                       fstrcpy(c,tok[ptr+2]);
                        *(c+2)=0;
                        hour = atoi(c);
                        *(c+5)=0;
@@ -103,7 +103,7 @@ Modified to handle file names with spaces, like the parse_lpq_lprng code
 further below.
 ****************************************************************************/
 
-static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
+static bool parse_lpq_bsd(char *line,print_queue_struct *buf,bool first)
 {
 #ifdef OSF1
 #define        RANKTOK 0
@@ -126,9 +126,14 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
 
        char *tok[MAXTOK];
        int  count = 0;
-       pstring line2;
+       TALLOC_CTX *ctx = talloc_tos();
+       char *line2 = NULL;
+       char *saveptr;
 
-       pstrcpy(line2,line);
+       line2 = talloc_strdup(ctx, line);
+       if (!line2) {
+               return false;
+       }
 
 #ifdef OSF1
        {
@@ -140,11 +145,12 @@ 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");
+       /* FIXME: Use next_token_talloc rather than strtok! */
+       tok[0] = strtok_r(line2," \t", &saveptr);
        count++;
 
-       while ((count < MAXTOK) && ((tok[count] = strtok(NULL," \t")) != NULL)) {
+       while ((count < MAXTOK)
+              && ((tok[count] = strtok_r(NULL, " \t", &saveptr)) != NULL)) {
                count++;
        }
 
@@ -176,7 +182,7 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
                        fstrcat(buf->fs_file, tok[i]);
                }
                /* Ensure null termination. */
-               fstrterminate(buf->fs_file);
+               buf->fs_file[sizeof(buf->fs_file)-1] = '\0';
        }
 
 #ifdef PRIOTOK
@@ -240,7 +246,7 @@ static time_t LPRng_time(char *time_string)
 
 ****************************************************************************/
 
-static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
+static bool parse_lpq_lprng(char *line,print_queue_struct *buf,bool first)
 {
 #define        LPRNG_RANKTOK   0
 #define        LPRNG_USERTOK   1
@@ -252,22 +258,26 @@ 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. */
 
-       fstring tokarr[LPRNG_MAXTOK];
+       char *tokarr[LPRNG_MAXTOK];
        const char *cptr;
        char *ptr;
        int num_tok = 0;
+       TALLOC_CTX *frame = talloc_stackframe();
 
        cptr = line;
-       while((num_tok < LPRNG_MAXTOK) && next_token( &cptr, tokarr[num_tok], " \t", sizeof(fstring))) {
+       while((num_tok < LPRNG_MAXTOK) && next_token_talloc(frame, &cptr,
+                               &tokarr[num_tok], " \t")) {
                num_tok++;
        }
 
        /* We must get at least LPRNG_NTOK tokens. */
        if (num_tok < LPRNG_NTOK) {
+               TALLOC_FREE(frame);
                return False;
        }
 
        if (!isdigit((int)*tokarr[LPRNG_JOBTOK]) || !isdigit((int)*tokarr[LPRNG_TOTALTOK])) {
+               TALLOC_FREE(frame);
                return False;
        }
 
@@ -311,9 +321,10 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
                        fstrcat(buf->fs_file, tokarr[i]);
                }
                /* Ensure null termination. */
-               fstrterminate(buf->fs_file);
+               buf->fs_file[sizeof(buf->fs_file)-1] = '\0';
        }
 
+       TALLOC_FREE(frame);
        return True;
 }
 
@@ -330,18 +341,20 @@ lazer   lazer RUNNING   537 6297doc.A          kvintus@IE    0 10  2445   1   1
               QUEUED    541 P.ps               root@IEDVB            22   1   5
 ********************************************************************/
 
-static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
+static bool parse_lpq_aix(char *line,print_queue_struct *buf,bool first)
 {
-       fstring tok[11];
+       char *tok[11];
        int count=0;
        const char *cline = line;
+       TALLOC_CTX *frame = talloc_stackframe();
 
        /* handle the case of "(standard input)" as a filename */
        string_sub(line,"standard input","STDIN",0);
        all_string_sub(line,"(","\"",0);
        all_string_sub(line,")","\"",0);
 
-       for (count=0; count<10 && next_token(&cline,tok[count],NULL, sizeof(tok[count])); count++) {
+       for (count=0; count<10 &&
+                       next_token_talloc(frame,&cline,&tok[count],NULL); count++) {
                ;
        }
 
@@ -350,21 +363,24 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
                if ((count == 7) && ((strcmp(tok[0],"QUEUED") == 0) || (strcmp(tok[0],"HELD") == 0))) {
                        /* the 2nd and 5th columns must be integer */
                        if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4])) {
+                               TALLOC_FREE(frame);
                                return False;
                        }
                        buf->size = atoi(tok[4]) * 1024;
                        /* if the fname contains a space then use STDIN */
                        if (strchr_m(tok[2],' ')) {
-                               fstrcpy(tok[2],"STDIN");
+                               tok[2] = talloc_strdup(frame,"STDIN");
+                               if (!tok[2]) {
+                                       TALLOC_FREE(frame);
+                                       return false;
+                               }
                        }
 
                        /* only take the last part of the filename */
                        {
-                               fstring tmp;
                                char *p = strrchr_m(tok[2],'/');
                                if (p) {
-                                       fstrcpy(tmp,p+1);
-                                       fstrcpy(tok[2],tmp);
+                                       tok[2] = p+1;
                                }
                        }
 
@@ -376,27 +392,31 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
                        fstrcpy(buf->fs_file,tok[2]);
                } else {
                        DEBUG(6,("parse_lpq_aix count=%d\n", count));
+                       TALLOC_FREE(frame);
                        return False;
                }
        } else {
                /* the 4th and 9th columns must be integer */
                if (!isdigit((int)*tok[3]) || !isdigit((int)*tok[8])) {
+                       TALLOC_FREE(frame);
                        return False;
                }
 
                buf->size = atoi(tok[8]) * 1024;
                /* if the fname contains a space then use STDIN */
                if (strchr_m(tok[4],' ')) {
-                       fstrcpy(tok[4],"STDIN");
+                       tok[4] = talloc_strdup(frame,"STDIN");
+                       if (!tok[4]) {
+                               TALLOC_FREE(frame);
+                               return false;
+                       }
                }
 
                /* only take the last part of the filename */
                {
-                       fstring tmp;
                        char *p = strrchr_m(tok[4],'/');
                        if (p) {
-                               fstrcpy(tmp,p+1);
-                               fstrcpy(tok[4],tmp);
+                               tok[4] = p+1;
                        }
                }
 
@@ -408,6 +428,7 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
                fstrcpy(buf->fs_file,tok[4]);
        }
 
+       TALLOC_FREE(frame);
        return True;
 }
 
@@ -422,11 +443,11 @@ 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;
-       static fstring jobuser;
+       static bool header_line_ok=False, base_prio_reset=False;
+       static char *jobuser;
        static int jobid;
        static int jobprio;
        static time_t jobtime;
@@ -435,12 +456,13 @@ static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
                with -p option first, to work */
        static int base_prio;
        int count;
-       char htab = '\011';  
+       char htab = '\011';
        const char *cline = line;
-       fstring tok[12];
+       char *tok[12];
+       TALLOC_CTX *frame = talloc_stackframe();
 
        /* If a line begins with a horizontal TAB, it is a subline type */
-  
+
        if (line[0] == htab) { /* subline */
                /* check if it contains the base priority */
                if (!strncmp(line,"\tfence priority : ",18)) {
@@ -449,6 +471,7 @@ static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
                }
 
                if (!header_line_ok) {
+                       TALLOC_FREE(frame);
                        return  False; /* incorrect header line */
                }
 
@@ -456,35 +479,48 @@ static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
                string_sub(line,"standard input","STDIN",0);
                all_string_sub(line,"(","\"",0);
                all_string_sub(line,")","\"",0);
-    
-               for (count=0; count<2 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) {
+
+               for (count=0; count<2 &&
+                               next_token_talloc(frame, &cline, &tok[count],NULL);
+                               count++) {
                        ;
                }
                /* we must get 2 tokens */
                if (count < 2) {
+                       TALLOC_FREE(frame);
                        return False;
                }
-    
+
                /* the 2nd column must be integer */
                if (!isdigit((int)*tok[1])) {
+                       TALLOC_FREE(frame);
                        return False;
                }
-    
+
                /* if the fname contains a space then use STDIN */
                if (strchr_m(tok[0],' ')) {
-                       fstrcpy(tok[0],"STDIN");
+                       tok[0] = talloc_strdup(frame, "STDIN");
+                       if (!tok[0]) {
+                               TALLOC_FREE(frame);
+                               return false;
+                       }
                }
-    
+
                buf->size = atoi(tok[1]);
                fstrcpy(buf->fs_file,tok[0]);
-    
+
                /* fill things from header line */
                buf->time = jobtime;
                buf->job = jobid;
                buf->status = jobstat;
                buf->priority = jobprio;
-               fstrcpy(buf->fs_user,jobuser);
-    
+               if (jobuser) {
+                       fstrcpy(buf->fs_user,jobuser);
+               } else {
+                       buf->fs_user[0] = '\0';
+               }
+
+               TALLOC_FREE(frame);
                return True;
        } else { /* header line */
                header_line_ok=False; /* reset it */
@@ -496,28 +532,33 @@ 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 */
                string_sub(line,"-"," ",0);
-    
-               for (count=0; count<12 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) {
+
+               for (count=0; count<12 &&
+                               next_token_talloc(frame, &cline, &tok[count],NULL);
+                               count++) {
                        ;
                }
-      
+
                /* we must get 8 tokens */
                if (count < 8) {
+                       TALLOC_FREE(frame);
                        return False;
                }
-    
+
                /* first token must be printer name (cannot check ?) */
                /* the 2nd, 5th & 7th column must be integer */
                if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4]) || !isdigit((int)*tok[6])) {
+                       TALLOC_FREE(frame);
                        return False;
                }
                jobid = atoi(tok[1]);
-               fstrcpy(jobuser,tok[2]);
+               SAFE_FREE(jobuser);
+               jobuser = SMB_STRDUP(tok[2]);
                jobprio = atoi(tok[4]);
-    
+
                /* process time */
                jobtime=EntryTime(tok, 5, count, 8);
                if (jobprio < base_prio) {
@@ -532,8 +573,9 @@ static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
                                jobstat = LPQ_PRINTING;
                        }
                }
-    
+
                header_line_ok=True; /* information is correct */
+               TALLOC_FREE(frame);
                return False; /* need subline info to include into queuelist */
        }
 }
@@ -548,14 +590,15 @@ dcslw-897               tridge            4712   Dec 20 10:30:30 being held
 
 ****************************************************************************/
 
-static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
+static bool parse_lpq_sysv(char *line,print_queue_struct *buf,bool first)
 {
-       fstring tok[9];
+       char *tok[9];
        int count=0;
        char *p;
        const char *cline = line;
+       TALLOC_CTX *frame = NULL;
 
-       /* 
+       /*
         * Handle the dash in the job id, but make sure that we skip over
         * the printer name in case we have a dash in that.
         * Patch from Dom.Mitchell@palmerharvey.co.uk.
@@ -580,28 +623,32 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
                *p = ' ';
        }
 
-       for (count=0; count<9 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) {
+       frame = talloc_stackframe();
+       for (count=0; count<9 &&
+                       next_token_talloc(frame, &cline, &tok[count],NULL);
+                       count++) {
                ;
        }
 
        /* we must get 7 tokens */
        if (count < 7) {
+               TALLOC_FREE(frame);
                return False;
        }
 
        /* the 2nd and 4th, 6th columns must be integer */
        if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[3])) {
+               TALLOC_FREE(frame);
                return False;
        }
        if (!isdigit((int)*tok[5])) {
+               TALLOC_FREE(frame);
                return False;
        }
 
-       /* if the user contains a ! then trim the first part of it */  
+       /* if the user contains a ! then trim the first part of it */
        if ((p=strchr_m(tok[2],'!'))) {
-               fstring tmp;
-               fstrcpy(tmp,p+1);
-               fstrcpy(tok[2],tmp);
+               tok[2] = p+1;
        }
 
        buf->job = atoi(tok[1]);
@@ -617,6 +664,7 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
        buf->time = EntryTime(tok, 4, count, 7);
        fstrcpy(buf->fs_user,tok[2]);
        fstrcpy(buf->fs_file,tok[2]);
+       TALLOC_FREE(frame);
        return True;
 }
 
@@ -625,17 +673,18 @@ parse a lpq line
 
 here is an example of lpq output under qnx
 Spooler: /qnx/spooler, on node 1
-Printer: txt        (ready) 
+Printer: txt        (ready)
 0000:     root [job #1    ]   active 1146 bytes        /etc/profile
 0001:     root [job #2    ]    ready 2378 bytes        /etc/install
 0002:     root [job #3    ]    ready 1146 bytes        -- standard input --
 ****************************************************************************/
 
-static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
+static bool parse_lpq_qnx(char *line,print_queue_struct *buf,bool first)
 {
-       fstring tok[7];
+       char *tok[7];
        int count=0;
        const char *cline = line;
+       TALLOC_CTX *frame = NULL;
 
        DEBUG(4,("antes [%s]\n", line));
 
@@ -650,30 +699,33 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
        string_sub(line,"]","",0);
        DEBUG(4,("despues 2 [%s]\n", line));
 
-       for (count=0; count<7 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) {
+       frame = talloc_stackframe();
+       for (count=0; count<7 &&
+                       next_token_talloc(frame,&cline,&tok[count],NULL);
+                       count++) {
                ;
        }
 
        /* we must get 7 tokens */
        if (count < 7) {
+               TALLOC_FREE(frame);
                return False;
        }
 
        /* the 3rd and 5th columns must be integer */
        if (!isdigit((int)*tok[2]) || !isdigit((int)*tok[4])) {
+               TALLOC_FREE(frame);
                return False;
        }
 
        /* only take the last part of the filename */
        {
-               fstring tmp;
                char *p = strrchr_m(tok[6],'/');
                if (p) {
-                       fstrcpy(tmp,p+1);
-                       fstrcpy(tok[6],tmp);
+                       tok[6] = p+1;
                }
        }
-       
+
        buf->job = atoi(tok[2]);
        buf->size = atoi(tok[4]);
        buf->status = strequal(tok[3],"active")?LPQ_PRINTING:LPQ_QUEUED;
@@ -681,6 +733,7 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
        buf->time = time(NULL);
        fstrcpy(buf->fs_user,tok[1]);
        fstrcpy(buf->fs_file,tok[6]);
+       TALLOC_FREE(frame);
        return True;
 }
 
@@ -698,39 +751,49 @@ Local  Printer 'lp2' (fjall):
 
 ****************************************************************************/
 
-static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
+static bool parse_lpq_plp(char *line,print_queue_struct *buf,bool first)
 {
-       fstring tok[11];
+       char *tok[11];
        int count=0;
        const char *cline = line;
+       TALLOC_CTX *frame = talloc_stackframe();
 
        /* handle the case of "(standard input)" as a filename */
        string_sub(line,"stdin","STDIN",0);
        all_string_sub(line,"(","\"",0);
        all_string_sub(line,")","\"",0);
-  
-       for (count=0; count<11 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) {
+
+       for (count=0; count<11 &&
+                       next_token_talloc(frame,&cline,&tok[count],NULL);
+                       count++) {
                ;
        }
 
        /* we must get 11 tokens */
        if (count < 11) {
+               TALLOC_FREE(frame);
                return False;
        }
 
        /* the first must be "active" or begin with an integer */
        if (strcmp(tok[0],"active") && !isdigit((int)tok[0][0])) {
+               TALLOC_FREE(frame);
                return False;
        }
 
        /* the 5th and 8th must be integer */
        if (!isdigit((int)*tok[4]) || !isdigit((int)*tok[7])) {
+               TALLOC_FREE(frame);
                return False;
        }
 
        /* if the fname contains a space then use STDIN */
        if (strchr_m(tok[6],' ')) {
-               fstrcpy(tok[6],"STDIN");
+               tok[6] = talloc_strdup(frame, "STDIN");
+               if (!tok[6]) {
+                       TALLOC_FREE(frame);
+                       return false;
+               }
        }
 
        /* only take the last part of the filename */
@@ -738,8 +801,9 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
                fstring tmp;
                char *p = strrchr_m(tok[6],'/');
                if (p) {
+                       size_t len = strlen(tok[6])+1;
                        fstrcpy(tmp,p+1);
-                       fstrcpy(tok[6],tmp);
+                       strlcpy(tok[6],tmp, len);
                }
        }
 
@@ -758,6 +822,7 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
        buf->time = time(NULL);
        fstrcpy(buf->fs_user,tok[1]);
        fstrcpy(buf->fs_file,tok[6]);
+       TALLOC_FREE(frame);
        return True;
 }
 
@@ -775,7 +840,7 @@ jmcd        Waiting   Re: Samba Open Sour     26     32476      1      1
 
 ********************************************************************/
 
-static BOOL parse_lpq_nt(char *line,print_queue_struct *buf,BOOL first)
+static bool parse_lpq_nt(char *line,print_queue_struct *buf,bool first)
 {
 #define LPRNT_OWNSIZ 11
 #define LPRNT_STATSIZ 9
@@ -795,51 +860,52 @@ static BOOL parse_lpq_nt(char *line,print_queue_struct *buf,BOOL first)
                char terminator;
        } nt_lpq_line;
 
-       nt_lpq_line parse_line;
+       char parse_line_char[sizeof(nt_lpq_line)];
+       nt_lpq_line *parse_line = (nt_lpq_line *)parse_line_char;
 #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);
+       memset(parse_line_char, '\0', sizeof(parse_line_char));
+       strncpy(parse_line_char, line, sizeof(parse_line_char) -1);
 
-       if (strlen((char *) &parse_line) != sizeof(parse_line) - 1) {
+       if (strlen(parse_line_char) != sizeof(parse_line_char) - 1) {
                return False;
        }
 
        /* Just want the first word in the owner field - the username */
-       if (strchr_m(parse_line.owner, ' ')) {
-               *(strchr_m(parse_line.owner, ' ')) = '\0';
+       if (strchr_m(parse_line->owner, ' ')) {
+               *(strchr_m(parse_line->owner, ' ')) = '\0';
        } else {
-               parse_line.space1 = '\0';
+               parse_line->space1 = '\0';
        }
 
        /* Make sure we have an owner */
-       if (!strlen(parse_line.owner)) {
+       if (!strlen(parse_line->owner)) {
                return False;
        }
 
        /* 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)) {
+       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', ' ');
+       parse_line->space3 = '\0';
+       trim_char(parse_line->jobname, '\0', ' ');
 
-       buf->job = atoi(parse_line.jobid);
+       buf->job = atoi(parse_line->jobid);
        buf->priority = 0;
-       buf->size = atoi(parse_line.size);
+       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)) {
+       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)) {
+       } else if (strequal(parse_line->status, LPRNT_PAUSED)) {
                buf->status = LPQ_PAUSED;
        } else {
                buf->status = LPQ_QUEUED;
@@ -858,7 +924,7 @@ JobID  File Name          Rank      Size        Status          Comment
 
 ********************************************************************/
 
-static BOOL parse_lpq_os2(char *line,print_queue_struct *buf,BOOL first)
+static bool parse_lpq_os2(char *line,print_queue_struct *buf,bool first)
 {
 #define LPROS2_IDSIZ 5
 #define LPROS2_JOBSIZ 15
@@ -878,48 +944,49 @@ static BOOL parse_lpq_os2(char *line,print_queue_struct *buf,BOOL first)
                char terminator;
        } os2_lpq_line;
 
-       os2_lpq_line parse_line;
+       char parse_line_char[sizeof(os2_lpq_line)];
+       os2_lpq_line *parse_line = (os2_lpq_line *)parse_line_char;
 #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);
+       memset(parse_line_char, '\0', sizeof(parse_line_char));
+       strncpy(parse_line_char, line, sizeof(parse_line_char) -1);
 
-       if (strlen((char *) &parse_line) != sizeof(parse_line) - 1) {
+       if (strlen(parse_line_char) != sizeof(parse_line_char) - 1) {
                return False;
        }
 
        /* Get the jobid */
-       buf->job = atoi(parse_line.jobid);
+       buf->job = atoi(parse_line->jobid);
 
        /* Get the job name */
-       parse_line.space2[0] = '\0';
-       trim_char(parse_line.jobname, '\0', ' ');
-       fstrcpy(buf->fs_file, parse_line.jobname);
+       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->size = atoi(parse_line->size);
        buf->time = time(NULL);
 
        /* Make sure we have an owner */
-       if (!strlen(parse_line.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)) {
+       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)) {
+       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)) {
+       } else if (strequal(parse_line->status, LPROS2_PAUSED)) {
                buf->status = LPQ_PAUSED;
        } else {
                buf->status = LPQ_QUEUED;
@@ -938,19 +1005,23 @@ static const char *stat2_strings[] = { "jam", "paper", "error", "responding", "n
 parse a vlp line
 ****************************************************************************/
 
-static BOOL parse_lpq_vlp(char *line,print_queue_struct *buf,BOOL first)
+static bool parse_lpq_vlp(char *line,print_queue_struct *buf,bool first)
 {
        int toknum = 0;
-       fstring tok;
+       char *tok;
+       TALLOC_CTX *frame = talloc_stackframe();
        const char *cline = line;
 
        /* First line is printer status */
 
-       if (!isdigit(line[0])) return False;
+       if (!isdigit(line[0])) {
+               TALLOC_FREE(frame);
+               return False;
+       }
 
        /* Parse a print job entry */
 
-       while(next_token(&cline, tok, NULL, sizeof(fstring))) {
+       while(next_token_talloc(frame, &cline, &tok, NULL)) {
                switch (toknum) {
                case 0:
                        buf->job = atoi(tok);
@@ -974,6 +1045,7 @@ static BOOL parse_lpq_vlp(char *line,print_queue_struct *buf,BOOL first)
                toknum++;
        }
 
+       TALLOC_FREE(frame);
        return True;
 }
 
@@ -983,11 +1055,11 @@ static BOOL parse_lpq_vlp(char *line,print_queue_struct *buf,BOOL first)
 parse a lpq line. Choose printing style
 ****************************************************************************/
 
-BOOL parse_lpq_entry(enum printing_types printing_type,char *line,
+bool parse_lpq_entry(enum printing_types printing_type,char *line,
                     print_queue_struct *buf,
-                    print_status_struct *status,BOOL first)
+                    print_status_struct *status,bool first)
 {
-       BOOL ret;
+       bool ret;
 
        switch (printing_type) {
                case PRINT_SYSV:
@@ -1080,3 +1152,23 @@ BOOL parse_lpq_entry(enum printing_types printing_type,char *line,
 
        return ret;
 }
+
+/****************************************************************************
+ Parse a file name from the system spooler to generate a jobid.
+****************************************************************************/
+
+uint32_t print_parse_jobid(const char *fname)
+{
+       int jobid;
+       const char *p = strstr_m(fname,PRINT_SPOOL_PREFIX);
+
+       if (!p) {
+               return (uint32_t)-1;
+       }
+       p += strlen(PRINT_SPOOL_PREFIX);
+       jobid = atoi(p);
+       if (jobid <= 0) {
+               return (uint32_t)-1;
+       }
+       return (uint32_t)jobid;
+}