Пример #1
0
/****************************************************************************
delete a printer queue entry
****************************************************************************/
void del_printqueue(int cnum,int snum,int jobid)
{
  char *lprm_command = lp_lprmcommand(snum);
  char *printername = PRINTERNAME(snum);
  pstring syscmd;
  char jobstr[20];
  int ret;

  if (!printername || !*printername)
    {
      DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n",
	    lp_servicename(snum),snum));
      printername = lp_servicename(snum);
    }
    
  if (!lprm_command || !(*lprm_command))
    {
      DEBUG(5,("No lprm command\n"));
      return;
    }
    
  slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid);

  pstrcpy(syscmd,lprm_command);
  string_sub(syscmd,"%p",printername);
  string_sub(syscmd,"%j",jobstr);
  standard_sub(cnum,syscmd);

  ret = smbrun(syscmd,NULL,False);
  DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));  
  lpq_reset(snum); /* queue has changed */
}
Пример #2
0
/****************************************************************************
change status of a printer queue entry
****************************************************************************/
void status_printjob(int cnum,int snum,int jobid,int status)
{
  char *lpstatus_command = 
    (status==LPQ_PAUSED?lp_lppausecommand(snum):lp_lpresumecommand(snum));
  char *printername = PRINTERNAME(snum);
  pstring syscmd;
  char jobstr[20];
  int ret;

  if (!printername || !*printername)
    {
      DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n",
	    lp_servicename(snum),snum));
      printername = lp_servicename(snum);
    }
    
  if (!lpstatus_command || !(*lpstatus_command))
    {
      DEBUG(5,("No lpstatus command to %s job\n",
	       (status==LPQ_PAUSED?"pause":"resume")));
      return;
    }
    
  slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid);

  pstrcpy(syscmd,lpstatus_command);
  string_sub(syscmd,"%p",printername);
  string_sub(syscmd,"%j",jobstr);
  standard_sub(cnum,syscmd);

  ret = smbrun(syscmd,NULL,False);
  DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));  
  lpq_reset(snum); /* queue has changed */
}
Пример #3
0
/****************************************************************************
Build the print command in the supplied buffer. This means getting the
print command for the service and inserting the printer name and the
print file name. Return NULL on error, else the passed buffer pointer.
****************************************************************************/
static char *build_print_command(int cnum, char *command, char *syscmd, char *filename1)
{
  int snum = SNUM(cnum);
  char *tstr;
  pstring filename;
  
  /* get the print command for the service. */
  tstr = command;
  if (!syscmd || !tstr) {
    DEBUG(0,("No print command for service `%s'\n", SERVICE(snum)));
    return (NULL);
  }

  /* copy the command into the buffer for extensive meddling. */
  StrnCpy(syscmd, tstr, sizeof(pstring) - 1);
  
  /* look for "%s" in the string. If there is no %s, we cannot print. */   
  if (!strstr(syscmd, "%s") && !strstr(syscmd, "%f")) {
    DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum)));
  }
  
  if (strstr(syscmd,"%s")) {
    int iOffset = PTR_DIFF(strstr(syscmd, "%s"),syscmd);
    
    /* construct the full path for the filename, shouldn't be necessary unless
       the subshell causes a "cd" to be executed.
       Only use the full path if there isn't a / preceding the %s */
    if (iOffset==0 || syscmd[iOffset-1] != '/') {
      StrnCpy(filename,Connections[cnum].connectpath,sizeof(filename)-1);
      trim_string(filename,"","/");
      pstrcat(filename,"/");
      pstrcat(filename,filename1);
    }
    else
      pstrcpy(filename,filename1);
    
    string_sub(syscmd, "%s", filename);
  }
  
  string_sub(syscmd, "%f", filename1);
  
  /* Does the service have a printername? If not, make a fake and empty    */
  /* printer name. That way a %p is treated sanely if no printer */
  /* name was specified to replace it. This eventuality is logged.         */
  tstr = PRINTERNAME(snum);
  if (tstr == NULL || tstr[0] == '\0') {
    DEBUG(3,( "No printer name - using %s.\n", SERVICE(snum)));
    tstr = SERVICE(snum);
  }
  
  string_sub(syscmd, "%p", tstr);
  
  standard_sub(cnum,syscmd);
  
  return (syscmd);
}
Пример #4
0
/****************************************************************************
  parse a lpq line for the plp printing system
  Bertrand Wallrich <*****@*****.**>

redone by tridge. Here is a sample queue:

Local  Printer 'lp2' (fjall):
  Printing (started at Jun 15 13:33:58, attempt 1).
    Rank Owner       Pr Opt  Job Host        Files           Size     Date
  active tridge      X  -    6   fjall       /etc/hosts      739      Jun 15 13:33
     3rd tridge      X  -    7   fjall       /etc/hosts      739      Jun 15 13:33

****************************************************************************/
static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
{
  fstring tok[11];
  int count=0;

  /* handle the case of "(standard input)" as a filename */
  string_sub(line,"stdin","STDIN");
  string_sub(line,"(","\"");
  string_sub(line,")","\"");
  
  for (count=0; count<11 && next_token(&line,tok[count],NULL); count++) ;

  /* we must get 11 tokens */
  if (count < 11)
    return(False);

  /* the first must be "active" or begin with an integer */
  if (strcmp(tok[0],"active") && !isdigit(tok[0][0]))
    return(False);

  /* the 5th and 8th must be integer */
  if (!isdigit(*tok[4]) || !isdigit(*tok[7])) 
    return(False);

  /* if the fname contains a space then use STDIN */
  if (strchr(tok[6],' '))
    fstrcpy(tok[6],"STDIN");

  /* only take the last part of the filename */
  {
    fstring tmp;
    char *p = strrchr(tok[6],'/');
    if (p)
      {
        fstrcpy(tmp,p+1);
        fstrcpy(tok[6],tmp);
      }
  }


  buf->job = atoi(tok[4]);

  buf->size = atoi(tok[7]);
  if (strchr(tok[7],'K'))
    buf->size *= 1024;
  if (strchr(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);
  return(True);
}
Пример #5
0
/****************************************************************************
parse a lpq line

here is an example of lpq output under qnx
Spooler: /qnx/spooler, on node 1
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)
{
  fstring tok[7];
  int count=0;

  DEBUG(0,("antes [%s]\n", line));

  /* handle the case of "-- standard input --" as a filename */
  string_sub(line,"standard input","STDIN");
  DEBUG(0,("despues [%s]\n", line));
  string_sub(line,"-- ","\"");
  string_sub(line," --","\"");
  DEBUG(0,("despues 1 [%s]\n", line));

  string_sub(line,"[job #","");
  string_sub(line,"]","");
  DEBUG(0,("despues 2 [%s]\n", line));

  
  
  for (count=0; count<7 && next_token(&line,tok[count],NULL); count++) ;

  /* we must get 7 tokens */
  if (count < 7)
    return(False);

  /* the 3rd and 5th columns must be integer */
  if (!isdigit(*tok[2]) || !isdigit(*tok[4])) return(False);

  /* only take the last part of the filename */
  {
    fstring tmp;
    char *p = strrchr(tok[6],'/');
    if (p)
      {
	fstrcpy(tmp,p+1);
	fstrcpy(tok[6],tmp);
      }
  }
	

  buf->job = atoi(tok[2]);
  buf->size = atoi(tok[4]);
  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);
  return(True);
}
Пример #6
0
REGISTRY_HOOK* reghook_cache_find( char *keyname )
{
	char *key;
	int len;
	REGISTRY_HOOK *hook;
	
	if ( !keyname )
		return NULL;
	
	/* prepend the string with a '\' character */
	
	len = strlen( keyname );
	if ( !(key = SMB_MALLOC( len + 2 )) ) {
		DEBUG(0,("reghook_cache_find: malloc failed for string [%s] !?!?!\n",
			keyname));
		return NULL;
	}

	*key = '\\';
	strncpy( key+1, keyname, len+1);
	
	/* swap to a form understood by the SORTED_TREE */

	string_sub( key, "\\", "/", 0 );
		
	DEBUG(10,("reghook_cache_find: Searching for keyname [%s]\n", key));
	
	hook = pathtree_find( cache_tree, key ) ;
	
	SAFE_FREE( key );
	
	return hook;
}
Пример #7
0
static bool test_string_sub_multiple(struct torture_context *tctx)
{
	char tmp[100];
	safe_strcpy(tmp, "fooblafoo", sizeof(tmp));
	string_sub(tmp, "foo", "bar", sizeof(tmp));
	torture_assert_str_equal(tctx, tmp, "barblabar", "invalid sub");
	return true;
}
Пример #8
0
static bool test_string_sub_special_char(struct torture_context *tctx)
{
	char tmp[100];
	safe_strcpy(tmp, "foobla", sizeof(tmp));
	string_sub(tmp, "foo", "%b;l", sizeof(tmp));
	torture_assert_str_equal(tctx, tmp, "_b_lbla", "invalid sub");
	return true;
}
Пример #9
0
/* remove a particular element from a header list */
void header_remove_list(char *label, char *content)
{
    struct header *h = header_find(label);
    char *p;

    if (!h) return;

    p = strstr(h->content, content);
    if (!p) return;

    if (!strchr(h->content,',')) {
        header_remove(label);
        return;
    }

    string_sub(h->content, content, "");
    string_sub(h->content, ", ,", ",");
    trim_string(h->content," ", " ");
    trim_string(h->content,",", ",");
}
Пример #10
0
static void standard_sub_advanced(int snum, const char *user, 
				  const char *connectpath, gid_t gid, 
				  const char *smb_name, char *str, size_t len)
{
	char *p, *s, *home;

	for (s=str; (p=strchr_m(s, '%'));s=p) {
		int l = (int)len - (int)(p-str);
	
		if (l < 0)
			l = 0;
	
		switch (*(p+1)) {
		case 'N' :
			string_sub(p,"%N", automount_server(user),l);
			break;
		case 'H':
			if ((home = get_user_home_dir(user)))
				string_sub(p,"%H",home, l);
			else
				p += 2;
			break;
		case 'P': 
			string_sub(p,"%P", connectpath, l); 
			break;
		case 'S': 
			string_sub(p,"%S", lp_servicename(snum), l); 
			break;
		case 'g': 
			string_sub(p,"%g", gidtoname(gid), l); 
			break;
		case 'u': 
			string_sub(p,"%u", user, l); 
			break;
			
			/* Patch from [email protected] Left the %N (NIS
			 * server name) in standard_sub_basic as it is
			 * a feature for logon servers, hence uses the
			 * username.  The %p (NIS server path) code is
			 * here as it is used instead of the default
			 * "path =" string in [homes] and so needs the
			 * service name, not the username.  */
		case 'p': 
			string_sub(p,"%p", automount_path(lp_servicename(snum)), l); 
			break;
		case '\0': 
			p++; 
			break; /* don't run off the end of the string */
			
		default: p+=2; 
			break;
		}
	}

	standard_sub_basic(smb_name, str, len);
}
Пример #11
0
/****************************************************************************
check if a username is valid
****************************************************************************/
BOOL user_ok(char *user,int snum)
{
  pstring valid, invalid;
  BOOL ret;

  StrnCpy(valid, lp_valid_users(snum), sizeof(pstring));
  StrnCpy(invalid, lp_invalid_users(snum), sizeof(pstring));

  string_sub(valid,"%S",lp_servicename(snum));
  string_sub(invalid,"%S",lp_servicename(snum));

  ret = !user_in_list(user,invalid);

  if (ret && valid && *valid)
    ret = user_in_list(user,valid);

  if (ret && lp_onlyuser(snum)) {
    char *user_list = lp_username(snum);
    string_sub(user_list,"%S",lp_servicename(snum));
    ret = user_in_list(user,user_list);
  }

  return(ret);
}
Пример #12
0
static size_t expand_env_var(char *p, int len)
{
	fstring envname;
	char *envval;
	char *q, *r;
	int copylen;

	if (p[1] != '$')
		return 1;

	if (p[2] != '(')
		return 2;

	/*
	 * Look for the terminating ')'.
	 */

	if ((q = strchr_m(p,')')) == NULL) {
		DEBUG(0,("expand_env_var: Unterminated environment variable [%s]\n", p));
		return 2;
	}

	/*
	 * Extract the name from within the %$(NAME) string.
	 */

	r = p+3;
	copylen = MIN((q-r),(sizeof(envname)-1));
	strncpy(envname,r,copylen);
	envname[copylen] = '\0';

	if ((envval = getenv(envname)) == NULL) {
		DEBUG(0,("expand_env_var: Environment variable [%s] not set\n", envname));
		return 2;
	}

	/*
	 * Copy the full %$(NAME) into envname so it
	 * can be replaced.
	 */

	copylen = MIN((q+1-p),(sizeof(envname)-1));
	strncpy(envname,p,copylen);
	envname[copylen] = '\0';
	string_sub(p,envname,envval,len);
	return 0; /* Allow the environment contents to be parsed. */
}
Пример #13
0
/****************************************************************************
parse a lpq line

here is an example of "lpstat -o dcslw" output under sysv

dcslw-896               tridge            4712   Dec 20 10:30:30 on dcslw
dcslw-897               tridge            4712   Dec 20 10:30:30 being held

****************************************************************************/
static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
{
  fstring tok[9];
  int count=0;
  char *p;

  /* handle the dash in the job id */
  string_sub(line,"-"," ");
  
  for (count=0; count<9 && next_token(&line,tok[count],NULL); count++) ;

  /* we must get 7 tokens */
  if (count < 7)
    return(False);

  /* the 2nd and 4th, 6th columns must be integer */
  if (!isdigit(*tok[1]) || !isdigit(*tok[3])) return(False);
  if (!isdigit(*tok[5])) return(False);

  /* if the user contains a ! then trim the first part of it */  
  if ((p=strchr(tok[2],'!')))
    {
      fstring tmp;
      fstrcpy(tmp,p+1);
      fstrcpy(tok[2],tmp);
    }
    

  buf->job = atoi(tok[1]);
  buf->size = atoi(tok[3]);
  if (count > 7 && strequal(tok[7],"on"))
    buf->status = LPQ_PRINTING;
  else if (count > 8 && strequal(tok[7],"being") && strequal(tok[8],"held"))
    buf->status = LPQ_PAUSED;
  else
    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);
  return(True);
}
Пример #14
0
/****************************************************************************
check for authority to login to a service with a given username/password
****************************************************************************/
BOOL authorise_login(int snum,char *user,char *password, int pwlen, 
		     BOOL *guest,BOOL *force,uint16 vuid)
{
  BOOL ok = False;
  
  *guest = False;
  
#if DEBUG_PASSWORD
  DEBUG(100,("checking authorisation on user=%s pass=%s\n",user,password));
#endif

  /* there are several possibilities:
     1) login as the given user with given password
     2) login as a previously registered username with the given password
     3) login as a session list username with the given password
     4) login as a previously validated user/password pair
     5) login as the "user ="******"user ="******"ACCEPTED: given username password ok\n"));
      }

      /* check for a previously registered guest username */
      if (!ok && (vuser != 0) && vuser->guest) {	  
	if (user_ok(vuser->name,snum) &&
	    password_ok(vuser->name, password, pwlen, NULL)) {
	  pstrcpy(user, vuser->name);
	  vuser->guest = False;
	  DEBUG(3,("ACCEPTED: given password with registered user %s\n", user));
	  ok = True;
	}
      }


      /* now check the list of session users */
      if (!ok)
	{
	  char *auser;
	  char *user_list = strdup(session_users);
	  if (!user_list) return(False);

	  for (auser=strtok(user_list,LIST_SEP); 
	       !ok && auser; 
	       auser = strtok(NULL,LIST_SEP))
	    {
	      fstring user2;
	      fstrcpy(user2,auser);
	      if (!user_ok(user2,snum)) continue;
		  
	      if (password_ok(user2,password, pwlen, NULL)) {
		ok = True;
		pstrcpy(user,user2);
		DEBUG(3,("ACCEPTED: session list username and given password ok\n"));
	      }
	    }
	  free(user_list);
	}

      /* check for a previously validated username/password pair */
      if (!ok && (!lp_revalidate(snum) || lp_security() > SEC_SHARE) &&
	  (vuser != 0) && !vuser->guest &&
	  user_ok(vuser->name,snum)) {
	pstrcpy(user,vuser->name);
	*guest = False;
	DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n"));
	ok = True;
      }

      /* check for a rhosts entry */
      if (!ok && user_ok(user,snum) && check_hosts_equiv(user)) {
	ok = True;
	DEBUG(3,("ACCEPTED: hosts equiv or rhosts entry\n"));
      }

      /* check the user= fields and the given password */
      if (!ok && lp_username(snum)) {
	char *auser;
	pstring user_list;
	StrnCpy(user_list,lp_username(snum),sizeof(pstring));

	string_sub(user_list,"%S",lp_servicename(snum));
	  
	for (auser=strtok(user_list,LIST_SEP);
	     auser && !ok;
	     auser = strtok(NULL,LIST_SEP))
	  {
	    if (*auser == '@')
	      {
		auser = validate_group(auser+1,password,pwlen,snum);
		if (auser)
		  {
		    ok = True;
		    pstrcpy(user,auser);
		    DEBUG(3,("ACCEPTED: group username and given password ok\n"));
		  }
	      }
	    else
	      {
		fstring user2;
		fstrcpy(user2,auser);
		if (user_ok(user2,snum) && 
		    password_ok(user2,password,pwlen,NULL))
		  {
		    ok = True;
		    pstrcpy(user,user2);
		    DEBUG(3,("ACCEPTED: user list username and given password ok\n"));
		  }
	      }
	  }
      }      
    } /* not guest only */

  /* check for a normal guest connection */
  if (!ok && GUEST_OK(snum))
    {
      fstring guestname;
      StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1);
      if (Get_Pwnam(guestname,True))
	{
	  pstrcpy(user,guestname);
	  ok = True;
	  DEBUG(3,("ACCEPTED: guest account and guest ok\n"));
	}
      else
	DEBUG(0,("Invalid guest account %s??\n",guestname));
      *guest = True;
      *force = True;
    }

  if (ok && !user_ok(user,snum))
    {
      DEBUG(0,("rejected invalid user %s\n",user));
      ok = False;
    }

  return(ok);
}
Пример #15
0
/****************************************************************************
parse a lpq line
here is an example of lpq output under hpux; note there's no space after -o !
$> lpstat -oljplus
ljplus-2153         user           priority 0  Jan 19 08:14 on ljplus
      util.c                                  125697 bytes
      server.c				      110712 bytes
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)
{
  /* 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 int jobid;
  static int jobprio;
  static time_t jobtime;
  static int jobstat=LPQ_QUEUED;
  /* to store minimum priority to print, lpstat command should be invoked
     with -p option first, to work */
  static int base_prio;
 
  int count;
  char TAB = '\011';  
  fstring tok[12];

  /* If a line begins with a horizontal TAB, it is a subline type */
  
  if (line[0] == TAB) { /* subline */
    /* check if it contains the base priority */
    if (!strncmp(line,"\tfence priority : ",18)) {
       base_prio=atoi(&line[18]);
       DEBUG(4, ("fence priority set at %d\n", base_prio));
    }
    if (!header_line_ok) return (False); /* incorrect header line */
    /* handle the case of "(standard input)" as a filename */
    string_sub(line,"standard input","STDIN");
    string_sub(line,"(","\"");
    string_sub(line,")","\"");
    
    for (count=0; count<2 && next_token(&line,tok[count],NULL); count++) ;
    /* we must get 2 tokens */
    if (count < 2) return(False);
    
    /* the 2nd column must be integer */
    if (!isdigit(*tok[1])) return(False);
    
    /* if the fname contains a space then use STDIN */
    if (strchr(tok[0],' '))
      fstrcpy(tok[0],"STDIN");
    
    buf->size = atoi(tok[1]);
    StrnCpy(buf->file,tok[0],sizeof(buf->file)-1);
    
    /* 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);
    
    return(True);
  }
  else { /* header line */
    header_line_ok=False; /* reset it */
    if (first) {
       if (!base_prio_reset) {
	  base_prio=0; /* reset it */
	  base_prio_reset=True;
       }
    }
    else if (base_prio) base_prio_reset=False;
    
    /* handle the dash in the job id */
    string_sub(line,"-"," ");
    
    for (count=0; count<12 && next_token(&line,tok[count],NULL); count++) ;
      
    /* we must get 8 tokens */
    if (count < 8) return(False);
    
    /* first token must be printer name (cannot check ?) */
    /* the 2nd, 5th & 7th column must be integer */
    if (!isdigit(*tok[1]) || !isdigit(*tok[4]) || !isdigit(*tok[6])) return(False);
    jobid = atoi(tok[1]);
    StrnCpy(jobuser,tok[2],sizeof(buf->user)-1);
    jobprio = atoi(tok[4]);
    
    /* process time */
    jobtime=EntryTime(tok, 5, count, 8);
    if (jobprio < base_prio) {
       jobstat = LPQ_PAUSED;
       DEBUG (4, ("job %d is paused: prio %d < %d; jobstat=%d\n", jobid, jobprio, base_prio, jobstat));
    }
    else {
       jobstat = LPQ_QUEUED;
       if ((count >8) && (((strequal(tok[8],"on")) ||
			   ((strequal(tok[8],"from")) && 
			    ((count > 10)&&(strequal(tok[10],"on")))))))
	 jobstat = LPQ_PRINTING;
    }
    
    header_line_ok=True; /* information is correct */
    return(False); /* need subline info to include into queuelist */
  }
}
Пример #16
0
/*******************************************************************
parse lpq on an aix system

Queue   Dev   Status    Job Files              User         PP %   Blks  Cp Rnk
------- ----- --------- --- ------------------ ---------- ---- -- ----- --- ---
lazer   lazer READY
lazer   lazer RUNNING   537 6297doc.A          kvintus@IE    0 10  2445   1   1
              QUEUED    538 C.ps               root@IEDVB           124   1   2
              QUEUED    539 E.ps               root@IEDVB            28   1   3
              QUEUED    540 L.ps               root@IEDVB           172   1   4
              QUEUED    541 P.ps               root@IEDVB            22   1   5
********************************************************************/
static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
{
  fstring tok[11];
  int count=0;

  /* handle the case of "(standard input)" as a filename */
  string_sub(line,"standard input","STDIN");
  string_sub(line,"(","\"");
  string_sub(line,")","\"");

  for (count=0; count<10 && next_token(&line,tok[count],NULL); count++) ;

  /* we must get 6 tokens */
  if (count < 10)
  {
      if ((count == 7) && ((strcmp(tok[0],"QUEUED") == 0) || (strcmp(tok[0],"HELD") == 0)))
      {
          /* the 2nd and 5th columns must be integer */
          if (!isdigit(*tok[1]) || !isdigit(*tok[4])) return(False);
          buf->size = atoi(tok[4]) * 1024;
          /* if the fname contains a space then use STDIN */
          if (strchr(tok[2],' '))
            fstrcpy(tok[2],"STDIN");

          /* only take the last part of the filename */
          {
            fstring tmp;
            char *p = strrchr(tok[2],'/');
            if (p)
              {
                fstrcpy(tmp,p+1);
                fstrcpy(tok[2],tmp);
              }
          }


          buf->job = atoi(tok[1]);
          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);
      }
      else
      {
          DEBUG(6,("parse_lpq_aix count=%d\n", count));
          return(False);
      }
  }
  else
  {
      /* the 4th and 9th columns must be integer */
      if (!isdigit(*tok[3]) || !isdigit(*tok[8])) return(False);
      buf->size = atoi(tok[8]) * 1024;
      /* if the fname contains a space then use STDIN */
      if (strchr(tok[4],' '))
        fstrcpy(tok[4],"STDIN");

      /* only take the last part of the filename */
      {
        fstring tmp;
        char *p = strrchr(tok[4],'/');
        if (p)
          {
            fstrcpy(tmp,p+1);
            fstrcpy(tok[4],tmp);
          }
      }


      buf->job = atoi(tok[3]);
      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);
  }


  return(True);
}
Пример #17
0
/****************************************************************************
  parse a lpq line
  <*****@*****.**>
  Most of the code is directly reused from parse_lpq_bsd()

here are two examples of lpq output under lprng (LPRng-2.3.0)

Printer: humprn@hum-fak
  Queue: 1 printable job
  Server: pid 4840 active, Unspooler: pid 4841 active
  Status: job 'cfA659hum-fak', closing device at Fri Jun 21 10:10:21 1996
 Rank  Owner           Class Job Files                           Size Time
active magnus@hum-fak      A 659 /var/spool/smb/Notesblok-ikke-na4024 10:03:31
 
Printer: humprn@hum-fak (printing disabled)
  Queue: 1 printable job
  Warning: no server present
  Status: finished operations at Fri Jun 21 10:10:32 1996
 Rank  Owner           Class Job Files                           Size Time
1      magnus@hum-fak      A 387 /var/spool/smb/netbudget.xls    21230 10:50:53

******************************************************************************

NEW FOR LPRng-3.3.5 !

<*****@*****.**> 
This will not happen anymore: with LPRng-3.3.5 there is always a blank between
the filename and the size, and the format has changed:

Printer: lj6@lizard  'HP LaserJet 6P'
 Queue: 2 printable jobs
 Server: pid 11941 active
 Unspooler: pid 11942 active
 Status: printed all 1818 bytes at 19:49:59
 Rank   Owner/ID                   Class Job  Files               Size Time
active  root@lizard+937                A  937 (stdin)            1818 19:49:58
2       root@lizard+969                A  969 junk.txt           2170 19:50:12
 
****************************************************************************/
static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
{
#define        LPRNG_RANKTOK   0
#define        LPRNG_USERTOK 1
#define        LPRNG_PRIOTOK 2
#define        LPRNG_JOBTOK    3
#define        LPRNG_FILETOK   4
#define        LPRNG_TOTALTOK 5
#define LPRNG_TIMETOK 6
#define        LPRNG_NTOK      7

/****************************************************************************
From lpd_status.c in LPRng source.
0        1         2         3         4         5         6         7
12345678901234567890123456789012345678901234567890123456789012345678901234 
" Rank  Owner           Class Job Files                           Size Time"
                        plp_snprintf( msg, sizeof(msg), "%-6s %-19s %c %03d %-32s",
                                number, line, priority, cfp->number, error );
                                plp_snprintf( msg + len, sizeof(msg)-len, "%4d",
                                        cfp->jobsize );
                                plp_snprintf( msg+len, sizeof(msg)-len, " %s",
                                        Time_str( 1, cfp->statb.st_ctime ) );
****************************************************************************/
  /* The following define's are to be able to adjust the values if the
LPRng source changes.  This is from version 2.3.0.  Magnus  */
#define SPACE_W 1
#define RANK_W 6
#define OWNER_W 19
#define CLASS_W 1
#define JOB_W 3
#define FILE_W 32
/* The JOBSIZE_W is too small for big jobs, so time is pushed to the right */
#define JOBSIZE_W 4
 
#define RANK_POS 0
#define OWNER_POS RANK_POS+RANK_W+SPACE_W
#define CLASS_POS OWNER_POS+OWNER_W+SPACE_W
#define JOB_POS CLASS_POS+CLASS_W+SPACE_W
#define FILE_POS JOB_POS+JOB_W+SPACE_W
#define JOBSIZE_POS FILE_POS+FILE_W

  
  fstring tok[LPRNG_NTOK];
  int count=0;

#ifdef OLD_LPRNG
/* We only need this bugfix for older versions of lprng - current
   information is that version 3.3.5 must not have this line
   in order to work correctly.
*/

/* 
Need to insert one space in front of the size, to be able to use
next_token() unchanged.  I would have liked to be able to insert a
space instead, to prevent losing that one char, but perl has spoiled
me :-\  So I did it the easiest way.

HINT: Use as short a path as possible for the samba spool directory.
A long spool-path will just waste significant chars of the file name.
*/

  line[JOBSIZE_POS-1]=' ';
#endif /* OLD_LPRNG */

  /* handle the case of "(stdin)" as a filename */
  string_sub(line,"stdin","STDIN");
  string_sub(line,"(","\"");
  string_sub(line,")","\"");
  
  for (count=0; count<LPRNG_NTOK && next_token(&line,tok[count],NULL); count++) ;

  /* we must get LPRNG_NTOK tokens */
  if (count < LPRNG_NTOK)
    return(False);

  /* the Job and Total columns must be integer */
  if (!isdigit(*tok[LPRNG_JOBTOK]) || !isdigit(*tok[LPRNG_TOTALTOK])) return(False);

  /* if the fname contains a space then use STDIN */
  /* I do not understand how this would be possible. Magnus. */
  if (strchr(tok[LPRNG_FILETOK],' '))
    fstrcpy(tok[LPRNG_FILETOK],"STDIN");

  /* only take the last part of the filename */
  {
    fstring tmp;
    char *p = strrchr(tok[LPRNG_FILETOK],'/');
    if (p)
      {
       fstrcpy(tmp,p+1);
       fstrcpy(tok[LPRNG_FILETOK],tmp);
      }
  }
       

  buf->job = atoi(tok[LPRNG_JOBTOK]);
  buf->size = atoi(tok[LPRNG_TOTALTOK]);
  if (strequal(tok[LPRNG_RANKTOK],"active"))
    buf->status = LPQ_PRINTING;
  else if (strequal(tok[LPRNG_RANKTOK],"hold"))
    buf->status = LPQ_PAUSED;
  else
    buf->status = LPQ_QUEUED;
  /*  buf->time = time(NULL); */
  buf->time = LPRng_time(tok,LPRNG_TIMETOK);
DEBUG(3,("Time reported for job %d is %s", buf->job, ctime(&buf->time)));
  StrnCpy(buf->user,tok[LPRNG_USERTOK],sizeof(buf->user)-1);
  StrnCpy(buf->file,tok[LPRNG_FILETOK],sizeof(buf->file)-1);
#ifdef LPRNG_PRIOTOK
  /* Here I try to map the CLASS char to a number, but the number
     is never shown in Print Manager under NT anyway... Magnus. */
  buf->priority = atoi(tok[LPRNG_PRIOTOK]-('A'-1));
#else
  buf->priority = 1;
#endif
  return(True);
}
Пример #18
0
/****************************************************************************
parse a lpq line

here is an example of lpq output under bsd

Warning: no daemon present
Rank   Owner      Job  Files                                 Total Size
1st    tridge     148  README                                8096 bytes

here is an example of lpq output under osf/1

Warning: no daemon present
Rank   Pri Owner      Job  Files                             Total Size
1st    0   tridge     148  README                            8096 bytes
****************************************************************************/
static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
{
#ifdef	OSF1
#define	RANKTOK	0
#define	PRIOTOK 1
#define	USERTOK 2
#define	JOBTOK	3
#define	FILETOK	4
#define	TOTALTOK 5
#define	NTOK	6
#else	/* OSF1 */
#define	RANKTOK	0
#define	USERTOK 1
#define	JOBTOK	2
#define	FILETOK	3
#define	TOTALTOK 4
#define	NTOK	5
#endif	/* OSF1 */

  fstring tok[NTOK];
  int count=0;

#ifdef	OSF1
  int length;
  length = strlen(line);
  if (line[length-3] == ':')
	return(False);
#endif	/* OSF1 */

  /* handle the case of "(standard input)" as a filename */
  string_sub(line,"standard input","STDIN");
  string_sub(line,"(","\"");
  string_sub(line,")","\"");
  
  for (count=0; count<NTOK && next_token(&line,tok[count],NULL); count++) ;

  /* we must get NTOK tokens */
  if (count < NTOK)
    return(False);

  /* the Job and Total columns must be integer */
  if (!isdigit(*tok[JOBTOK]) || !isdigit(*tok[TOTALTOK])) return(False);

  /* if the fname contains a space then use STDIN */
  if (strchr(tok[FILETOK],' '))
    fstrcpy(tok[FILETOK],"STDIN");

  /* only take the last part of the filename */
  {
    fstring tmp;
    char *p = strrchr(tok[FILETOK],'/');
    if (p)
      {
	fstrcpy(tmp,p+1);
	fstrcpy(tok[FILETOK],tmp);
      }
  }
	

  buf->job = atoi(tok[JOBTOK]);
  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);
#ifdef PRIOTOK
  buf->priority = atoi(tok[PRIOTOK]);
#else
  buf->priority = 1;
#endif
  return(True);
}
Пример #19
0
void standard_sub_basic(const char *smb_name, char *str,size_t len)
{
	char *p, *s;
	fstring pidstr;
	struct passwd *pass;
	const char *local_machine_name = get_local_machine_name();

	for (s=str; (p=strchr_m(s, '%'));s=p) {
		fstring tmp_str;

		int l = (int)len - (int)(p-str);

		if (l < 0)
			l = 0;
		
		switch (*(p+1)) {
		case 'U' : 
			fstrcpy(tmp_str, smb_name);
			strlower_m(tmp_str);
			string_sub(p,"%U",tmp_str,l);
			break;
		case 'G' :
			fstrcpy(tmp_str, smb_name);
			if ((pass = Get_Pwnam(tmp_str))!=NULL) {
				string_sub(p,"%G",gidtoname(pass->pw_gid),l);
			} else {
				p += 2;
			}
			break;
		case 'D' :
			fstrcpy(tmp_str, current_user_info.domain);
			strupper_m(tmp_str);
			string_sub(p,"%D", tmp_str,l);
			break;
		case 'I' :
			string_sub(p,"%I", client_addr(),l);
			break;
		case 'i' :
			string_sub(p,"%i", client_socket_addr(),l);
			break;
		case 'L' : 
			if (local_machine_name && *local_machine_name)
				string_sub(p,"%L", local_machine_name,l); 
			else {
				pstring temp_name;

				pstrcpy(temp_name, global_myname());
				strlower_m(temp_name);
				string_sub(p,"%L", temp_name,l); 
			}
			break;
		case 'M' :
			string_sub(p,"%M", client_name(),l);
			break;
		case 'R' :
			string_sub(p,"%R", remote_proto,l);
			break;
		case 'T' :
			string_sub(p,"%T", timestring(False),l);
			break;
		case 'a' :
			string_sub(p,"%a", remote_arch,l);
			break;
		case 'd' :
			slprintf(pidstr,sizeof(pidstr)-1, "%d",(int)sys_getpid());
			string_sub(p,"%d", pidstr,l);
			break;
		case 'h' :
			string_sub(p,"%h", myhostname(),l);
			break;
		case 'm' :
			string_sub(p,"%m", get_remote_machine_name(),l);
			break;
		case 'v' :
			string_sub(p,"%v", SAMBA_VERSION_STRING,l);
			break;
		case '$' :
			p += expand_env_var(p,l);
			break; /* Expand environment variables */
		case '\0': 
			p++; 
			break; /* don't run off the end of the string */
			
		default: p+=2; 
			break;
		}
	}
}
Пример #20
0
void parser(_map *mem, const char *statement) {
	/*
	 * there're three occasions:
	 * (1) variable declaration
	 * (2) variable printing
	 * (3) variable assignment
	 */

	_vector *vec_statement = vector_new(8);
	int count = string_split(vec_statement, statement, ';');

	char *current_statement = (char *)malloc(sizeof(char));

	for (int i = 0; i < count; ++i) {

		size_t len = strlen((char *)*vector_get(vec_statement, i));
		current_statement = (char *)realloc(current_statement, sizeof(char) * (len + 1));
		strcpy(current_statement, (char *)*vector_get(vec_statement, i));

		if (!strcmp(current_statement, "")) {
			break;
		}

		bool is_assignment = true;

		// variable declaration
		char temp_str[1005]; // TODO(twd2): enough?
		const char double_declare[] = "double ";
		const char int_declare[] = "int ";
		const size_t double_declare_len = strlen(double_declare);
		const size_t int_declare_len = strlen(int_declare);

		int str_int_start_pos = string_startswith(current_statement, int_declare);
		int str_double_start_pos = string_startswith(current_statement, double_declare);

		if (str_double_start_pos != -1) {
			// variable declared as a double
			is_assignment = false;

			size_t j;
			for (j = str_double_start_pos + double_declare_len; j < len; ++j) {
				if (current_statement[j] != ' ') {
					break;
				}
			}
			string_sub(temp_str, current_statement, j, len);
			_vector *vec_declare = vector_new(8);
			int count = string_split(vec_declare, temp_str, ',');
			for (j = 0; j < count; ++j) {
				char *name_purified = string_purify((char *)(*vector_get(vec_declare, j)));
				add_double_variable(mem, name_purified, 0);
				free(name_purified);
			}
			vector_deepfree(vec_declare);
		}

		if (str_int_start_pos != -1) {
			// variable declared as a int
			is_assignment = false;

			size_t j;
			for (j = str_int_start_pos + int_declare_len; j < len; ++j) {
				if (current_statement[j] != ' ') {
					break;
				}
			}
			string_sub(temp_str, current_statement, j, len);
			_vector *vec_declare = vector_new(8);
			int count = string_split(vec_declare, temp_str, ',');
			for (j = 0; j < count; ++j) {
				char *name_purified = string_purify((char *)(*vector_get(vec_declare, j)));
				add_int_variable(mem, name_purified, 0);
				free(name_purified);
			}
			vector_deepfree(vec_declare);
		}

		// variable printing
		const char print_declare1[] = "print ";
		const char print_declare2[] = "print(";
		const size_t print_declare_len = strlen(print_declare1);

		if (string_startswith(current_statement, print_declare1) != -1 ||
			string_startswith(current_statement, print_declare2) != -1) {
			// print statement
			is_assignment = false;

			int j;
			for (j = print_declare_len - 1; j < len; ++j) {
				if (current_statement[j] == ')') {
					break;
				}
			}
			string_sub(temp_str, current_statement, print_declare_len, j - print_declare_len);
			string_clearspace(temp_str);
			parse(temp_str);
			convert(temp_str);
			_variable var = calculate(mem, temp_str);
			if (var.type == ERRORVALUE) {
				catch_error(var.int_value);
				break;
			}
			print_variable(&var);
		}

		// variable assignment
		if (is_assignment) {
			strcpy(temp_str, current_statement);
			string_clearspace(temp_str);
			parse(temp_str);
			convert(temp_str);
			_variable var = calculate(mem, temp_str);
			if (var.type == ERRORVALUE) {
				catch_error(var.int_value);
				break;
			}
		}

	}

	free(current_statement);
	vector_deepfree(vec_statement);
	return;
}
Пример #21
0
/**
 * @brief Setup the CGI framework.
 *
 * Setup the cgi framework, handling the possibility that this program
 * is either run as a true CGI program with a gateway to a web server, or
 * is itself a mini web server.
 **/
void cgi_setup(const char *rootdir, int auth_required)
{
	bool authenticated = False;
	char line[1024];
	char *url=NULL;
	char *p;
	char *lang;

	if (chdir(rootdir)) {
		cgi_setup_error("500 Server Error", "",
				"chdir failed - the server is not configured correctly");
	}

	/* Handle the possibility we might be running as non-root */
	sec_init();

	if ((lang=getenv("HTTP_ACCEPT_LANGUAGE"))) {
		/* if running as a cgi program */
		web_set_lang(lang);
	}

	/* maybe we are running under a web server */
	if (getenv("CONTENT_LENGTH") || getenv("REQUEST_METHOD")) {
		if (auth_required) {
			cgi_web_auth();
		}
		return;
	}

	inetd_server = True;

	if (!check_access(1, lp_hostsallow(-1), lp_hostsdeny(-1))) {
		cgi_setup_error("403 Forbidden", "",
				"Samba is configured to deny access from this client\n<br>Check your \"hosts allow\" and \"hosts deny\" options in smb.conf ");
	}

	/* we are a mini-web server. We need to read the request from stdin
	   and handle authentication etc */
	while (fgets(line, sizeof(line)-1, stdin)) {
		if (line[0] == '\r' || line[0] == '\n') break;
		if (strnequal(line,"GET ", 4)) {
			got_request = True;
			url = SMB_STRDUP(&line[4]);
		} else if (strnequal(line,"POST ", 5)) {
			got_request = True;
			request_post = 1;
			url = SMB_STRDUP(&line[5]);
		} else if (strnequal(line,"PUT ", 4)) {
			got_request = True;
			cgi_setup_error("400 Bad Request", "",
					"This server does not accept PUT requests");
		} else if (strnequal(line,"Authorization: ", 15)) {
			authenticated = cgi_handle_authorization(&line[15]);
		} else if (strnequal(line,"Content-Length: ", 16)) {
			content_length = atoi(&line[16]);
		} else if (strnequal(line,"Accept-Language: ", 17)) {
			web_set_lang(&line[17]);
		}
		/* ignore all other requests! */
	}

	if (auth_required && !authenticated) {
		cgi_auth_error();
	}

	if (!url) {
		cgi_setup_error("400 Bad Request", "",
				"You must specify a GET or POST request");
	}

	/* trim the URL */
	if ((p = strchr_m(url,' ')) || (p=strchr_m(url,'\t'))) {
		*p = 0;
	}
	while (*url && strchr_m("\r\n",url[strlen(url)-1])) {
		url[strlen(url)-1] = 0;
	}

	/* anything following a ? in the URL is part of the query string */
	if ((p=strchr_m(url,'?'))) {
		query_string = p+1;
		*p = 0;
	}

	string_sub(url, "/swat/", "", 0);

	if (url[0] != '/' && strstr(url,"..")==0) {
		cgi_download(url);
	}

	printf("HTTP/1.0 200 OK\r\nConnection: close\r\n");
	printf("Date: %s\r\n", http_timestring(time(NULL)));
	baseurl = "";
	pathinfo = url+1;
}
Пример #22
0
/****************************************************************************
parse a qstat line

here is an example of "qstat -l -d qms" output under softq

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


****************************************************************************/
static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first)
{
  fstring tok[10];
  int count=0;

  /* mung all the ":"s to spaces*/
  string_sub(line,":"," ");
  
  for (count=0; count<10 && next_token(&line,tok[count],NULL); count++) ;

  /* we must get 9 tokens */
  if (count < 9)
    return(False);

  /* the 1st and 7th columns must be integer */
  if (!isdigit(*tok[0]) || !isdigit(*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(*tok[7]))
        return(False);
      buf->status = *tok[1] == '>' ? LPQ_PRINTING : LPQ_PAUSED;
      count = 1;
    }
  else
    {
      if (!isdigit(*tok[5]))
        return(False);
      buf->status = LPQ_QUEUED;
      count = 0;
    }
	

  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 */
  {
    time_t jobtime;
    struct tm *t;

    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]) + 1900; break;
    default:                t->tm_year = atoi(tok[count+2]) + 2000; break;
    }

    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; 
  }

  return(True);
}
Пример #23
0
/****************************************************************************
get a printer queue
****************************************************************************/
int get_printqueue(int snum,int cnum,print_queue_struct **queue,
		   print_status_struct *status)
{
  char *lpq_command = lp_lpqcommand(snum);
  char *printername = PRINTERNAME(snum);
  int ret=0,count=0;
  pstring syscmd;
  fstring outfile;
  pstring line;
  FILE *f;
  struct stat sbuf;
  BOOL dorun=True;
  int cachetime = lp_lpqcachetime();

  *line = 0;
  check_lpq_cache(snum);
  
  if (!printername || !*printername)
    {
      DEBUG(6,("xx replacing printer name with service (snum=(%s,%d))\n",
	       lp_servicename(snum),snum));
      printername = lp_servicename(snum);
    }
    
  if (!lpq_command || !(*lpq_command))
    {
      DEBUG(5,("No lpq command\n"));
      return(0);
    }
    
  pstrcpy(syscmd,lpq_command);
  string_sub(syscmd,"%p",printername);

  standard_sub(cnum,syscmd);

  slprintf(outfile,sizeof(outfile)-1, "%s/lpq.%08x",tmpdir(),str_checksum(syscmd));
  
  if (!lpq_cache_reset[snum] && cachetime && !stat(outfile,&sbuf)) 
    {
      if (time(NULL) - sbuf.st_mtime < cachetime) {
	DEBUG(3,("Using cached lpq output\n"));
	dorun = False;
      }
    }

  if (dorun) {
    ret = smbrun(syscmd,outfile,True);
    DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
  }

  lpq_cache_reset[snum] = False;

  f = fopen(outfile,"r");
  if (!f) {
    return(0);
  }

  if (status) {
    fstrcpy(status->message,"");
    status->status = LPSTAT_OK;
  }
      
  while (fgets(line,sizeof(pstring),f))
    {
      DEBUG(6,("QUEUE2: %s\n",line));

      *queue = Realloc(*queue,sizeof(print_queue_struct)*(count+1));
      if (! *queue)
	{
	  count = 0;
	  break;
	}

      bzero((char *)&(*queue)[count],sizeof(**queue));
	  
      /* parse it */
      if (!parse_lpq_entry(snum,line,&(*queue)[count],status,count==0))
	continue;
	  
      count++;
    }	      

  fclose(f);

  if (!cachetime) {
    unlink(outfile);
  } else {
    /* we only expect this to succeed on trapdoor systems, on normal systems
     the file is owned by root */
    chmod(outfile,0666);
  }
  return(count);
}