Fixed most memory leak and big-endian bug in the spoolss code.
[tprouty/samba.git] / source / rpc_server / srv_spoolss.c
1 /* 
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tridgell              1992-1998,
6  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
7  *  Copyright (C) Jean François Micouleau      1998-1999.
8  *  
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *  
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *  
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24
25 #include "includes.h"
26 #include "nterr.h"
27
28 extern int DEBUGLEVEL;
29 extern pstring global_myname;
30
31 #ifndef MAX_OPEN_PRINTERS
32 #define MAX_OPEN_PRINTERS 50
33 #endif
34
35 #define PRINTER_HANDLE_IS_PRINTER       0
36 #define PRINTER_HANDLE_IS_PRINTSERVER   1
37
38
39 /* structure to store the printer handles */
40 /* and a reference to what it's pointing to */
41 /* and the notify info asked about */
42 /* that's the central struct */
43 static struct
44 {
45   BOOL        open;
46   BOOL        document_started;
47   BOOL        page_started;
48   uint32      current_jobid;
49   uint32      document_fd;
50   uint32      document_lastwritten;
51   pstring     document_name;
52   pstring     job_name;
53   PRINTER_HND printer_hnd;
54   BOOL        printer_type;
55   union
56   {
57         fstring printername;
58         fstring printerservername;
59   } dev;
60   uint32 type;
61   uint32 access;
62   uint32 number_of_notify;
63   SPOOL_NOTIFY_OPTION_TYPE notify_info[MAX_PRINTER_NOTIFY+MAX_JOB_NOTIFY];
64 } Printer[MAX_OPEN_PRINTERS];
65
66 #define VALID_HANDLE(pnum)   (((pnum) >= 0) && ((pnum) < MAX_OPEN_PRINTERS))
67 #define OPEN_HANDLE(pnum)    (VALID_HANDLE(pnum) && Printer[pnum].open)
68
69 /****************************************************************************
70   initialise printer handle states...
71 ****************************************************************************/
72 void init_printer_hnd(void)
73 {
74         int i;
75         for (i = 0; i < MAX_OPEN_PRINTERS; i++)
76         {
77                 Printer[i].open = False;
78         }
79 }
80
81
82 /****************************************************************************
83   create a unique printer handle
84 ****************************************************************************/
85 static void create_printer_hnd(PRINTER_HND *hnd)
86 {
87         static uint32 prt_hnd_low  = 0;
88         static uint32 prt_hnd_high = 0;
89
90         if (hnd == NULL) return;
91
92         /* i severely doubt that prt_hnd_high will ever be non-zero... */
93         prt_hnd_low++;
94         if (prt_hnd_low == 0) prt_hnd_high++;
95
96         SIVAL(hnd->data, 0 , 0x0);          /* first bit must be null */
97         SIVAL(hnd->data, 4 , prt_hnd_low ); /* second bit is incrementing */
98         SIVAL(hnd->data, 8 , prt_hnd_high); /* second bit is incrementing */
99         SIVAL(hnd->data, 12, time(NULL));   /* something random */
100         SIVAL(hnd->data, 16, getpid());     /* something more random */
101 }
102
103 /****************************************************************************
104   clear an handle
105 ****************************************************************************/
106 static void clear_handle(PRINTER_HND *hnd)
107 {
108         bzero(hnd->data, PRINTER_HND_SIZE);
109 }
110
111 /****************************************************************************
112   find first available printer slot.  creates a printer handle for you.
113  ****************************************************************************/
114 static BOOL open_printer_hnd(PRINTER_HND *hnd)
115 {
116         int i;
117
118         for (i = 0; i < MAX_OPEN_PRINTERS; i++)
119         {
120                 if (!Printer[i].open)
121                 {
122                         Printer[i].open = True;                         
123                         create_printer_hnd(hnd);
124                         memcpy(&(Printer[i].printer_hnd), hnd, sizeof(*hnd));
125
126                         DEBUG(4,("Opened printer handle[%x] ", i));
127                         dump_data(4, hnd->data, sizeof(hnd->data));
128                         return True;
129                 }
130         }
131         DEBUG(1,("ERROR - open_printer_hnd: out of Printers Handles!\n"));
132         return False;
133 }
134
135 /****************************************************************************
136   find printer index by handle
137 ****************************************************************************/
138 static int find_printer_index_by_hnd(PRINTER_HND *hnd)
139 {
140         int i;
141
142         for (i = 0; i < MAX_OPEN_PRINTERS; i++)
143         {
144                 if (memcmp(&(Printer[i].printer_hnd), hnd, sizeof(*hnd)) == 0)
145                 {
146                         DEBUG(4,("Found printer handle[%x] ", i));
147                         dump_data(4, hnd->data, sizeof(hnd->data));
148                         return i;
149                 }
150         }
151         DEBUG(3,("Whoops, Printer handle not found: "));
152         dump_data(4, hnd->data, sizeof(hnd->data));
153         return -1;
154 }
155
156 /****************************************************************************
157   set printer handle type.
158 ****************************************************************************/
159 static BOOL set_printer_hnd_accesstype(PRINTER_HND *hnd, uint32 access_required)
160 {
161         int pnum = find_printer_index_by_hnd(hnd);
162
163         if (OPEN_HANDLE(pnum))
164         {
165                 DEBUG(4,("Setting printer access=%x (pnum=%x)\n",
166                           access_required, pnum));
167
168
169
170                 Printer[pnum].access = access_required;
171                 return True;            
172         }
173         else
174         {
175                 DEBUG(4,("Error setting printer type=%x (pnum=%x)",
176                           access_required, pnum));
177                 return False;
178         }
179         return False;
180 }
181
182 /****************************************************************************
183   set printer handle type.
184 ****************************************************************************/
185 static BOOL set_printer_hnd_printertype(PRINTER_HND *hnd, char *printername)
186 {
187         int pnum = find_printer_index_by_hnd(hnd);
188                 
189         if (OPEN_HANDLE(pnum))
190         {
191                 DEBUG(3,("Setting printer type=%s (pnum=%x)\n", printername, pnum));
192
193                 if ( strlen(printername) < 3 )
194                 {
195                         DEBUGADD(4,("A print server must have at least 1 char ! %s\n", printername));
196                         return False;
197                 }
198
199                 /* check if it's \\server or \\server\printer */                
200                 /* +2 is to skip the leading \\ */
201                 if (!strchr(printername+2, '\\'))
202                 {
203                         /* it's a print server */
204                         DEBUGADD(4,("Printer is a print server\n"));
205                         Printer[pnum].printer_type = PRINTER_HANDLE_IS_PRINTSERVER;
206                         return True;
207                 }
208                 else
209                 {
210                         /* it's a printer */
211                         DEBUGADD(4,("Printer is a printer\n"));
212                         Printer[pnum].printer_type = PRINTER_HANDLE_IS_PRINTER;
213                         return True;
214                 }       
215         }
216         else
217         {
218                 DEBUGADD(4,("Error setting printer name %s (pnum=%x)",
219                           printername, pnum));
220                 return False;
221         }
222         return False;
223 }
224
225 /****************************************************************************
226   set printer handle printername.
227 ****************************************************************************/
228 static BOOL set_printer_hnd_printername(PRINTER_HND *hnd, char *printername)
229 {
230         int pnum = find_printer_index_by_hnd(hnd);
231         char *back;
232         NT_PRINTER_INFO_LEVEL printer;
233         int snum;
234         int n_services=lp_numservices();
235         uint32 marche;
236         
237         if (OPEN_HANDLE(pnum))
238         {
239                 DEBUG(4,("Setting printer name=%s (len=%d) (pnum=%x)\n",
240                           printername,strlen(printername), pnum));
241                           
242                 switch (Printer[pnum].printer_type)
243                  {
244                    case PRINTER_HANDLE_IS_PRINTER:
245                         back=strchr(printername+2, '\\');
246                         back=back+1;
247                         DEBUGADD(5,("searching for %s (len=%d)\n", back,strlen(back)));
248                         /* 
249                          * store the Samba share name in it
250                          * in back we have the long printer name
251                          * need to iterate all the snum and do a 
252                          * get_a_printer each time to find the printer
253                          * faster to do it here than later.
254                          */
255                         for (snum=0;snum<n_services; snum++)
256                         {
257                                 if (lp_browseable(snum) && 
258                                     lp_snum_ok(snum) && 
259                                     lp_print_ok(snum) )
260                                 {
261                                         DEBUGADD(5,("get_printer_snum, share:%s\n",lp_servicename(snum)));
262                                         
263                                         marche=get_a_printer(&printer, 2, lp_servicename(snum));
264                                         DEBUGADD(6,("get_printer_snum, marche:%d\n",marche));
265                                                                                 
266                                         if ( marche==0 && ( strlen(printer.info_2->printername) == strlen(back) ) 
267                                              && ( !strncasecmp(printer.info_2->printername, back, strlen(back))) 
268                                            )
269                                         {
270                                                 DEBUGADD(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum));
271                                                 strncpy(Printer[pnum].dev.printername, lp_servicename(snum), strlen(lp_servicename(snum)));
272                                                 free_a_printer(printer, 2);
273                                                 return True;
274                                                 break;  
275                                         }
276                                         free_a_printer(printer, 2);
277                                 }
278                         }
279
280                         return False;
281                         break;          
282                    case PRINTER_HANDLE_IS_PRINTSERVER:
283                         strncpy(Printer[pnum].dev.printerservername, printername, strlen(printername));
284                         return True;
285                         break;
286                    default:
287                         return False;
288                         break;
289                  }
290         }
291         else
292         {
293                 DEBUG(0,("Error setting printer name=%s (pnum=%x)\n",
294                          printername , pnum));
295                 return False;
296         }
297 }
298
299 /****************************************************************************
300   return the snum of a printer corresponding to an handle
301 ****************************************************************************/
302 static BOOL get_printer_snum(PRINTER_HND *hnd, int *number)
303 {
304         int snum;
305         int pnum = find_printer_index_by_hnd(hnd);
306         int n_services=lp_numservices();
307                 
308         if (OPEN_HANDLE(pnum))
309         {
310                 switch (Printer[pnum].printer_type)
311                  {
312                    case PRINTER_HANDLE_IS_PRINTER:                 
313                         DEBUG(4,("get_printer_snum, short name:%s\n", Printer[pnum].dev.printername));                  
314                         for (snum=0;snum<n_services; snum++)
315                         {
316                                 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
317                                 {
318                                         DEBUG(4,("get_printer_snum, share:%s\n",lp_servicename(snum)));
319                                         if (   ( strlen(lp_servicename(snum)) == strlen( Printer[pnum].dev.printername ) ) 
320                                             && ( !strncasecmp(lp_servicename(snum), 
321                                                               Printer[pnum].dev.printername,
322                                                               strlen( lp_servicename(snum) ))) 
323                                            )
324                                         {
325                                                 DEBUG(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum));
326                                                 *number=snum;
327                                                 return True;
328                                                 break;  
329                                         }
330                                 }
331                         }
332                         return False;
333                         break;          
334                    case PRINTER_HANDLE_IS_PRINTSERVER:
335                         return False;
336                         break;
337                    default:
338                         return False;
339                         break;
340                  }
341         }
342         else
343         {
344                 DEBUG(3,("Error getting printer - take a nap quickly !\n"));
345                 return False;
346         }
347 }
348
349 /********************************************************************
350  ********************************************************************/
351 static BOOL handle_is_printserver(PRINTER_HND *handle)
352 {
353         int pnum=find_printer_index_by_hnd(handle);
354
355         if (OPEN_HANDLE(pnum))
356         {
357                 switch (Printer[pnum].printer_type)
358                 {
359                 case PRINTER_HANDLE_IS_PRINTSERVER:
360                         return True;
361                         break;
362                 case PRINTER_HANDLE_IS_PRINTER:
363                         return False;
364                         break;
365                 }               
366         }
367         return False;
368 }
369
370 /********************************************************************
371  ********************************************************************/
372 /*
373 static BOOL handle_is_printer(PRINTER_HND *handle)
374 {
375         return (!handle_is_printserver(handle));
376 }
377 */
378
379 /********************************************************************
380  * api_spoolss_open_printer
381  *
382  * called from the spoolss dispatcher
383  ********************************************************************/
384 static void spoolss_reply_open_printer(SPOOL_Q_OPEN_PRINTER *q_u, prs_struct *rdata)                                
385 {
386         SPOOL_R_OPEN_PRINTER r_u;
387         BOOL printer_open = False;
388         fstring name;
389         
390         /* some sanity check because you can open a printer or a print server */
391         /* aka: \\server\printer or \\server */
392         unistr2_to_ascii(name, &(q_u->printername), sizeof(name)-1);
393
394         DEBUGADD(3,("checking name: %s\n",name));
395
396         /* now the response */
397         r_u.status=0x00000000;
398         
399         printer_open = open_printer_hnd(&(r_u.handle));
400         set_printer_hnd_printertype(&(r_u.handle), name);
401         
402         if ( !set_printer_hnd_printername(&(r_u.handle), name) )
403         {
404                 r_u.status=0xC0000000|NT_STATUS_ACCESS_DENIED;
405         }
406         
407         set_printer_hnd_accesstype(&(r_u.handle), q_u->access_required);
408         
409         spoolss_io_r_open_printer("",&r_u,rdata,0);
410 }
411
412 /********************************************************************
413  * api_spoolss_open_printer
414  *
415  * called from the spoolss dispatcher
416  ********************************************************************/
417 static void api_spoolss_open_printer(pipes_struct *p, prs_struct *data, prs_struct *rdata)
418 {
419         SPOOL_Q_OPEN_PRINTER q_u;
420
421         /* grab the spoolss open policy */
422         spoolss_io_q_open_printer("", &q_u, data, 0);
423
424         /* construct reply.  always indicate success */
425         spoolss_reply_open_printer(&q_u, rdata);
426 }
427
428 /********************************************************************
429  ********************************************************************/
430 static BOOL getprinterdata_printer_server(fstring value, uint32 size, uint32 *type, 
431                                           uint32 *numeric_data, uint8 **data, uint32 *needed)
432 {               
433         int i;
434                 
435         if (!strcmp(value, "BeepEnabled"))
436         {
437                 *type          = 0x4;
438                 *data  = (uint8 *)malloc( 4*sizeof(uint8) );
439                 ZERO_STRUCTP(*data);
440                 (*data)[0]=0x01;
441                 (*data)[1]=0x00;
442                 (*data)[2]=0x00;
443                 (*data)[3]=0x00;
444                 *numeric_data  = 0x1; /* beep enabled */        
445                 *needed        = 0x4;                   
446                 return True;
447         }
448
449         if (!strcmp(value, "EventLog"))
450         {
451                 *type          = 0x4;
452                 *data  = (uint8 *)malloc( 4*sizeof(uint8) );
453                 ZERO_STRUCTP(*data);
454                 (*data)[0]=0x1B;
455                 (*data)[1]=0x00;
456                 (*data)[2]=0x00;
457                 (*data)[3]=0x00;
458                 *numeric_data  = 0x1B; /* Don't know ??? */     
459                 *needed        = 0x4;                   
460                 return True;
461         }
462
463         if (!strcmp(value, "NetPopup"))
464         {
465                 *type          = 0x4;
466                 *data  = (uint8 *)malloc( 4*sizeof(uint8) );
467                 ZERO_STRUCTP(*data);
468                 (*data)[0]=0x01;
469                 (*data)[1]=0x00;
470                 (*data)[2]=0x00;
471                 (*data)[3]=0x00;
472                 *numeric_data  = 0x1; /* popup enabled */       
473                 *needed        = 0x4;
474                 return True;
475         }
476
477         if (!strcmp(value, "MajorVersion"))
478         {
479                 *type          = 0x4;
480                 *data  = (uint8 *)malloc( 4*sizeof(uint8) );
481                 (*data)[0]=0x02;
482                 (*data)[1]=0x00;
483                 (*data)[2]=0x00;
484                 (*data)[3]=0x00;
485                 *numeric_data  = 0x2; /* it's 2, period. */     
486                 *needed        = 0x4;
487                 return True;
488         }
489
490         if (!strcmp(value, "DefaultSpoolDirectory"))
491         {
492                 pstring directory="You are using a Samba server";
493                 *type = 0x1;                    
494                 *data  = (uint8 *)malloc( size*sizeof(uint8) );
495                 ZERO_STRUCTP(*data);
496                 
497                 /* it's done by hand ready to go on the wire */
498                 for (i=0; i<strlen(directory); i++)
499                 {
500                         (*data)[2*i]=directory[i];
501                         (*data)[2*i+1]='\0';
502                 }                       
503                 *needed = 2*(strlen(directory)+1);
504                 return True;
505         }
506
507         if (!strcmp(value, "Architecture"))
508         {                       
509                 pstring directory="Windows NT x86";
510                 *type = 0x1;                    
511                 *data  = (uint8 *)malloc( size*sizeof(uint8) );
512                 ZERO_STRUCTP(*data);
513                 for (i=0; i<strlen(directory); i++)
514                 {
515                         (*data)[2*i]=directory[i];
516                         (*data)[2*i+1]='\0';
517                 }                       
518                 *needed = 2*(strlen(directory)+1);      
519                 return True;
520         }
521         
522         return False;
523 }
524
525 static BOOL getprinterdata_printer(PRINTER_HND *handle, fstring value, uint32 size, uint32 *type, 
526                                           uint32 *numeric_data, uint8 **data, uint32 *needed )
527 {
528         NT_PRINTER_INFO_LEVEL printer;
529         int pnum=0;
530         int snum=0;
531         uint8 *idata=NULL;
532         uint32 len;
533         
534         DEBUG(5,("getprinterdata_printer\n"));
535
536         pnum = find_printer_index_by_hnd(handle);
537         if (OPEN_HANDLE(pnum))
538         {
539                 get_printer_snum(handle, &snum);                
540                 get_a_printer(&printer, 2, lp_servicename(snum));
541                 
542                 if (get_specific_param(printer, 2, value, &idata, type, &len)) 
543                 {
544                         switch (*type)
545                         {
546                                 case 1:
547                                 case 3:
548                                 case 4:
549                                         *data  = (uint8 *)malloc( size*sizeof(uint8) );
550                                         bzero(*data, sizeof(uint8)*size);
551                                         memcpy(*data, idata, len>size?size:len);
552                                         *needed = len;
553                                         if (idata) free(idata);
554                                         break;
555                                 /*case 4:
556                                         *numeric_data=atoi(idata);
557                                         break;*/
558                         }
559                         return (True);
560                 }
561                 free_a_printer(printer, 2);
562         }
563
564         return (False);
565 }       
566
567 /********************************************************************
568  * api_spoolss_reply_getprinterdata
569  *
570  * called from api_spoolss_getprinterdata
571  ********************************************************************/
572 static void spoolss_reply_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *rdata)                                
573 {
574         SPOOL_R_GETPRINTERDATA r_u;
575         fstring value;
576         BOOL found;
577         int pnum = find_printer_index_by_hnd(&(q_u->handle));
578         
579         /* 
580          * Reminder: when it's a string, the length is in BYTES
581          * even if UNICODE is negociated.
582          *
583          * r_u.type is the kind of data
584          * 1 is a string
585          * 4 is a uint32
586          *
587          * I think it's documented in MSDN somewhere in
588          * the registry data type (yep it's linked ...)
589          * 
590          * JFM, 4/19/1999
591          */
592
593         if (OPEN_HANDLE(pnum))
594         {
595                 r_u.size  = q_u->size;
596                 r_u.status = 0x0;
597                 r_u.type   = 0x4;
598                 r_u.needed = 0x0;
599                 r_u.data   = NULL;
600                 r_u.numeric_data=0x0;
601                 
602                 unistr2_to_ascii(value, &(q_u->valuename), sizeof(value)-1);
603                 
604                 if (handle_is_printserver(&(q_u->handle)))
605                 {               
606                         found=getprinterdata_printer_server(value, r_u.size, 
607                                                             &(r_u.type), &(r_u.numeric_data),
608                                                             &(r_u.data), &(r_u.needed));
609                 }
610                 else
611                 {
612                         found=getprinterdata_printer(&(q_u->handle), value, r_u.size, 
613                                                      &(r_u.type), &(r_u.numeric_data),
614                                                      &(r_u.data), &(r_u.needed));
615                 }
616
617                 if (found==False)
618                 {
619                         /* reply this param doesn't exist */
620                         r_u.type   = 0x4;
621                         r_u.size   = 0x0;
622                         r_u.data   = NULL;
623                         r_u.numeric_data=0x0;
624                         r_u.needed = 0x0;
625                         r_u.status = ERROR_INVALID_PARAMETER;
626                 }
627                         
628                 spoolss_io_r_getprinterdata("", &r_u, rdata, 0);
629                 if (r_u.data) free(r_u.data);
630         }       
631 }
632
633 /********************************************************************
634  * api_spoolss_getprinterdata
635  *
636  * called from the spoolss dispatcher
637  ********************************************************************/
638 static void api_spoolss_getprinterdata(pipes_struct *p, prs_struct *data, 
639                                         prs_struct *rdata)
640 {
641         SPOOL_Q_GETPRINTERDATA q_u;
642
643         /* read the stream and fill the struct */
644         spoolss_io_q_getprinterdata("", &q_u, data, 0);
645
646         spoolss_reply_getprinterdata(&q_u,rdata);
647 }
648
649 /********************************************************************
650  * api_spoolss_reply_closeprinter
651  *
652  * called from api_spoolss_closeprinter
653  ********************************************************************/
654 static void spoolss_reply_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *rdata)                                
655 {
656         SPOOL_R_CLOSEPRINTER r_u;
657         
658         int pnum = find_printer_index_by_hnd(&(q_u->handle));
659
660         clear_handle(&(r_u.handle));
661
662         if (OPEN_HANDLE(pnum))
663         {
664                 Printer[pnum].open=False;
665                 r_u.status=0x0; 
666                 spoolss_io_r_closeprinter("",&r_u,rdata,0);
667         }
668         else
669         {
670                 r_u.status= 0xC0000000 | NT_STATUS_INVALID_HANDLE;      
671                 DEBUG(3,("Error closing printer handle (pnum=%x)\n", pnum));
672         }
673         
674         spoolss_io_r_closeprinter("",&r_u,rdata,0);
675 }
676
677 /********************************************************************
678  * api_spoolss_closeprinter
679  *
680  * called from the spoolss dispatcher
681  ********************************************************************/
682 static void api_spoolss_closeprinter(pipes_struct *p, prs_struct *data, 
683                                       prs_struct *rdata)
684 {
685         SPOOL_Q_CLOSEPRINTER q_u;
686
687         spoolss_io_q_closeprinter("", &q_u, data, 0);
688
689         spoolss_reply_closeprinter(&q_u,rdata);
690 }
691
692 /********************************************************************
693  * api_spoolss_reply_rffpcnex
694  *
695  * called from api_spoolss_rffpcnex (see this to understand)
696  ********************************************************************/
697 static void spoolss_reply_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, prs_struct *rdata)
698 {
699         SPOOL_R_RFFPCNEX r_u;
700         
701         r_u.status = 0x0000;
702
703         spoolss_io_r_rffpcnex("",&r_u,rdata,0);
704 }
705
706 /********************************************************************
707  * api_spoolss_rffpcnex
708  * ReplyFindFirstPrinterChangeNotifyEx
709  * called from the spoolss dispatcher
710  *
711  * jfmxxxx: before replying OK: status=0
712  * should do a rpc call to the workstation asking ReplyOpenPrinter
713  * have to code it, later.
714  *
715  * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
716  ********************************************************************/
717 static void api_spoolss_rffpcnex(pipes_struct *p, prs_struct *data, 
718                                   prs_struct *rdata)
719 {
720         SPOOL_Q_RFFPCNEX q_u;
721         
722         int i,j,k;
723
724         spoolss_io_q_rffpcnex("", &q_u, data, 0);
725
726         /* store the notify value in the printer struct */
727
728         i=find_printer_index_by_hnd(&(q_u.handle));
729
730         Printer[i].number_of_notify=q_u.option.count;
731
732         DEBUG(3,("Copying %x notify option info\n",Printer[i].number_of_notify));
733
734         for (j=0;j<Printer[i].number_of_notify;j++)
735         {
736                 Printer[i].notify_info[j].count=q_u.option.type[j].count;
737                 Printer[i].notify_info[j].type=q_u.option.type[j].type  ;
738                 
739                 DEBUG(4,("Copying %x info fields of type %x\n",
740                          Printer[i].notify_info[j].count,
741                          Printer[i].notify_info[j].type));
742                 for(k=0;k<Printer[i].notify_info[j].count;k++)
743                 {
744                         Printer[i].notify_info[j].fields[k]=q_u.option.type[j].fields[k];
745                 }
746         }
747         spoolss_reply_rffpcnex(&q_u,rdata);
748 }
749
750 /*******************************************************************
751  * fill a notify_info_data with the servername
752  ********************************************************************/
753 static void spoolss_notify_server_name(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
754 {
755         pstring temp_name;
756
757         snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
758
759         data->notify_data.data.length=strlen(temp_name);
760         ascii_to_unistr(data->notify_data.data.string, temp_name, sizeof(data->notify_data.data.string)-1);
761 }
762
763 /*******************************************************************
764  * fill a notify_info_data with the servicename
765  * jfmxxxx: it's incorrect should be long_printername
766  ********************************************************************/
767 static void spoolss_notify_printer_name(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
768 {
769 /*
770         data->notify_data.data.length=strlen(lp_servicename(snum));
771         ascii_to_unistr(data->notify_data.data.string, lp_servicename(snum), sizeof(data->notify_data.data.string)-1);
772 */
773         data->notify_data.data.length=strlen(printer->info_2->printername);
774         ascii_to_unistr(data->notify_data.data.string, 
775                         printer->info_2->printername, 
776                         sizeof(data->notify_data.data.string)-1);
777 }
778
779 /*******************************************************************
780  * fill a notify_info_data with the servicename
781  ********************************************************************/
782 static void spoolss_notify_share_name(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
783 {
784         data->notify_data.data.length=strlen(lp_servicename(snum));
785         ascii_to_unistr(data->notify_data.data.string,
786                         lp_servicename(snum), 
787                         sizeof(data->notify_data.data.string)-1);
788 }
789
790 /*******************************************************************
791  * fill a notify_info_data with the port name
792  ********************************************************************/
793 static void spoolss_notify_port_name(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
794 {
795         /* even if it's strange, that's consistant in all the code */
796
797         data->notify_data.data.length=strlen(lp_servicename(snum));
798         ascii_to_unistr(data->notify_data.data.string,
799                         lp_servicename(snum), 
800                         sizeof(data->notify_data.data.string)-1);
801 }
802
803 /*******************************************************************
804  * fill a notify_info_data with the printername
805  * jfmxxxx: it's incorrect, should be lp_printerdrivername()
806  * but it doesn't exist, have to see what to do
807  ********************************************************************/
808 static void spoolss_notify_driver_name(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
809 {
810         data->notify_data.data.length=strlen(printer->info_2->drivername);
811         ascii_to_unistr(data->notify_data.data.string, 
812                         printer->info_2->drivername, 
813                         sizeof(data->notify_data.data.string)-1);
814 }
815
816 /*******************************************************************
817  * fill a notify_info_data with the comment
818  ********************************************************************/
819 static void spoolss_notify_comment(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
820 {
821         data->notify_data.data.length=strlen(lp_comment(snum));
822         ascii_to_unistr(data->notify_data.data.string,
823                         lp_comment(snum),
824                         sizeof(data->notify_data.data.string)-1);
825 }
826
827 /*******************************************************************
828  * fill a notify_info_data with the comment
829  * jfm:xxxx incorrect, have to create a new smb.conf option
830  * location = "Room 1, floor 2, building 3"
831  ********************************************************************/
832 static void spoolss_notify_location(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
833 {
834         data->notify_data.data.length=strlen(printer->info_2->location);
835         ascii_to_unistr(data->notify_data.data.string, 
836                         printer->info_2->location, 
837                         sizeof(data->notify_data.data.string)-1);
838 }
839
840 /*******************************************************************
841  * fill a notify_info_data with the device mode
842  * jfm:xxxx don't to it for know but that's a real problem !!!
843  ********************************************************************/
844 static void spoolss_notify_devmode(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
845 {
846 }
847
848 /*******************************************************************
849  * fill a notify_info_data with the separator file name
850  * jfm:xxxx just return no file could add an option to smb.conf
851  * separator file = "separator.txt"
852  ********************************************************************/
853 static void spoolss_notify_sepfile(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
854 {
855         data->notify_data.data.length=strlen(printer->info_2->sepfile);
856         ascii_to_unistr(data->notify_data.data.string, 
857                         printer->info_2->sepfile, 
858                         sizeof(data->notify_data.data.string)-1);
859 }
860
861 /*******************************************************************
862  * fill a notify_info_data with the print processor
863  * jfm:xxxx return always winprint to indicate we don't do anything to it
864  ********************************************************************/
865 static void spoolss_notify_print_processor(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
866 {
867         data->notify_data.data.length=strlen(printer->info_2->printprocessor);
868         ascii_to_unistr(data->notify_data.data.string, 
869                         printer->info_2->printprocessor, 
870                         sizeof(data->notify_data.data.string)-1);
871 }
872
873 /*******************************************************************
874  * fill a notify_info_data with the print processor options
875  * jfm:xxxx send an empty string
876  ********************************************************************/
877 static void spoolss_notify_parameters(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
878 {
879         data->notify_data.data.length=strlen(printer->info_2->parameters);
880         ascii_to_unistr(data->notify_data.data.string, 
881                         printer->info_2->parameters, 
882                         sizeof(data->notify_data.data.string)-1);
883 }
884
885 /*******************************************************************
886  * fill a notify_info_data with the data type
887  * jfm:xxxx always send RAW as data type
888  ********************************************************************/
889 static void spoolss_notify_datatype(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
890 {
891         data->notify_data.data.length=strlen(printer->info_2->datatype);
892         ascii_to_unistr(data->notify_data.data.string, 
893                         printer->info_2->datatype, 
894                         sizeof(data->notify_data.data.string)-1);
895 }
896
897 /*******************************************************************
898  * fill a notify_info_data with the security descriptor
899  * jfm:xxxx send an null pointer to say no security desc
900  * have to implement security before !
901  ********************************************************************/
902 static void spoolss_notify_security_desc(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
903 {
904         data->notify_data.data.length=0;
905         data->notify_data.data.string[0]=0x00;
906 }
907
908 /*******************************************************************
909  * fill a notify_info_data with the attributes
910  * jfm:xxxx a samba printer is always shared
911  ********************************************************************/
912 static void spoolss_notify_attributes(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
913 {
914         data->notify_data.value[0] =   PRINTER_ATTRIBUTE_SHARED   \
915                                      | PRINTER_ATTRIBUTE_NETWORK  \
916                                      | PRINTER_ATTRIBUTE_RAW_ONLY ;
917 }
918
919 /*******************************************************************
920  * fill a notify_info_data with the priority
921  ********************************************************************/
922 static void spoolss_notify_priority(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
923 {
924         data->notify_data.value[0] = printer->info_2->priority;
925 }
926
927 /*******************************************************************
928  * fill a notify_info_data with the default priority
929  ********************************************************************/
930 static void spoolss_notify_default_priority(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
931 {
932         data->notify_data.value[0] = printer->info_2->default_priority;
933 }
934
935 /*******************************************************************
936  * fill a notify_info_data with the start time
937  ********************************************************************/
938 static void spoolss_notify_start_time(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
939 {
940         data->notify_data.value[0] = printer->info_2->starttime;
941 }
942
943 /*******************************************************************
944  * fill a notify_info_data with the until time
945  ********************************************************************/
946 static void spoolss_notify_until_time(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
947 {
948         data->notify_data.value[0] = printer->info_2->untiltime;
949 }
950
951 /*******************************************************************
952  * fill a notify_info_data with the status
953  ********************************************************************/
954 static void spoolss_notify_status(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
955 {
956         int count;
957         print_queue_struct *q=NULL;
958         print_status_struct status;
959
960         bzero(&status,sizeof(status));
961
962         count=get_printqueue(snum, conn, &q, &status);
963
964         data->notify_data.value[0]=(uint32) status.status;
965         if (q) free(q);
966 }
967
968 /*******************************************************************
969  * fill a notify_info_data with the number of jobs queued
970  ********************************************************************/
971 static void spoolss_notify_cjobs(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
972 {
973         print_queue_struct *q=NULL;
974         print_status_struct status;
975
976         bzero(&status,sizeof(status));
977
978         data->notify_data.value[0]=get_printqueue(snum, conn, &q, &status);
979         if (q) free(q);
980 }
981
982 /*******************************************************************
983  * fill a notify_info_data with the average ppm
984  ********************************************************************/
985 static void spoolss_notify_average_ppm(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
986 {
987         /* always respond 8 pages per minutes */
988         /* a little hard ! */
989         data->notify_data.value[0] = printer->info_2->averageppm;
990 }
991
992 /*******************************************************************
993  * fill a notify_info_data with 
994  ********************************************************************/
995 static void spoolss_notify_username(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
996 {
997         data->notify_data.data.length=strlen(queue->user);
998         ascii_to_unistr(data->notify_data.data.string, queue->user, sizeof(data->notify_data.data.string)-1);
999 }
1000
1001 /*******************************************************************
1002  * fill a notify_info_data with 
1003  ********************************************************************/
1004 static void spoolss_notify_job_status(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1005 {
1006         data->notify_data.value[0]=queue->status;
1007 }
1008
1009 /*******************************************************************
1010  * fill a notify_info_data with 
1011  ********************************************************************/
1012 static void spoolss_notify_job_name(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1013 {
1014         data->notify_data.data.length=strlen(queue->file);
1015         ascii_to_unistr(data->notify_data.data.string, queue->file, sizeof(data->notify_data.data.string)-1);
1016 }
1017
1018 /*******************************************************************
1019  * fill a notify_info_data with 
1020  ********************************************************************/
1021 static void spoolss_notify_job_status_string(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1022 {
1023         data->notify_data.data.length=strlen("En attente");
1024         ascii_to_unistr(data->notify_data.data.string, "En attente", sizeof(data->notify_data.data.string)-1);
1025 }
1026
1027 /*******************************************************************
1028  * fill a notify_info_data with 
1029  ********************************************************************/
1030 static void spoolss_notify_job_time(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1031 {
1032         data->notify_data.value[0]=0x0;
1033 }
1034
1035 /*******************************************************************
1036  * fill a notify_info_data with 
1037  ********************************************************************/
1038 static void spoolss_notify_job_size(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1039 {
1040         data->notify_data.value[0]=queue->size;
1041 }
1042
1043 /*******************************************************************
1044  * fill a notify_info_data with 
1045  ********************************************************************/
1046 static void spoolss_notify_job_position(connection_struct *conn, int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer)
1047 {
1048         data->notify_data.value[0]=queue->job;
1049 }
1050
1051 #define END 65535
1052
1053 struct s_notify_info_data_table notify_info_data_table[] =
1054 {
1055 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME,         "PRINTER_NOTIFY_SERVER_NAME",         POINTER,   spoolss_notify_server_name },
1056 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME,        "PRINTER_NOTIFY_PRINTER_NAME",        POINTER,   spoolss_notify_printer_name },
1057 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME,          "PRINTER_NOTIFY_SHARE_NAME",          POINTER,   spoolss_notify_share_name },
1058 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME,           "PRINTER_NOTIFY_PORT_NAME",           POINTER,   spoolss_notify_port_name },
1059 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME,         "PRINTER_NOTIFY_DRIVER_NAME",         POINTER,   spoolss_notify_driver_name },
1060 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT,             "PRINTER_NOTIFY_COMMENT",             POINTER,   spoolss_notify_comment },
1061 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION,            "PRINTER_NOTIFY_LOCATION",            POINTER,   spoolss_notify_location },
1062 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE,             "PRINTER_NOTIFY_DEVMODE",             POINTER,   spoolss_notify_devmode },
1063 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE,             "PRINTER_NOTIFY_SEPFILE",             POINTER,   spoolss_notify_sepfile },
1064 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR,     "PRINTER_NOTIFY_PRINT_PROCESSOR",     POINTER,   spoolss_notify_print_processor },
1065 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS,          "PRINTER_NOTIFY_PARAMETERS",          POINTER,   spoolss_notify_parameters },
1066 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE,            "PRINTER_NOTIFY_DATATYPE",            POINTER,   spoolss_notify_datatype },
1067 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER,   spoolss_notify_security_desc },
1068 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES,          "PRINTER_NOTIFY_ATTRIBUTES",          ONE_VALUE, spoolss_notify_attributes },
1069 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY,            "PRINTER_NOTIFY_PRIORITY",            ONE_VALUE, spoolss_notify_priority },
1070 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY,    "PRINTER_NOTIFY_DEFAULT_PRIORITY",    ONE_VALUE, spoolss_notify_default_priority },
1071 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME,          "PRINTER_NOTIFY_START_TIME",          ONE_VALUE, spoolss_notify_start_time },
1072 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME,          "PRINTER_NOTIFY_UNTIL_TIME",          ONE_VALUE, spoolss_notify_until_time },
1073 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS,              "PRINTER_NOTIFY_STATUS",              ONE_VALUE, spoolss_notify_status },
1074 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING,       "PRINTER_NOTIFY_STATUS_STRING",       POINTER,   NULL },
1075 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS,               "PRINTER_NOTIFY_CJOBS",               ONE_VALUE, spoolss_notify_cjobs },
1076 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM,         "PRINTER_NOTIFY_AVERAGE_PPM",         ONE_VALUE, spoolss_notify_average_ppm },
1077 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES,         "PRINTER_NOTIFY_TOTAL_PAGES",         POINTER,   NULL },
1078 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED,       "PRINTER_NOTIFY_PAGES_PRINTED",       POINTER,   NULL },
1079 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES,         "PRINTER_NOTIFY_TOTAL_BYTES",         POINTER,   NULL },
1080 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED,       "PRINTER_NOTIFY_BYTES_PRINTED",       POINTER,   NULL },
1081 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_PRINTER_NAME,            "JOB_NOTIFY_PRINTER_NAME",            POINTER,   spoolss_notify_printer_name },
1082 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_MACHINE_NAME,            "JOB_NOTIFY_MACHINE_NAME",            POINTER,   spoolss_notify_server_name },
1083 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_PORT_NAME,               "JOB_NOTIFY_PORT_NAME",               POINTER,   spoolss_notify_port_name },
1084 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_USER_NAME,               "JOB_NOTIFY_USER_NAME",               POINTER,   spoolss_notify_username },
1085 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_NOTIFY_NAME,             "JOB_NOTIFY_NOTIFY_NAME",             POINTER,   spoolss_notify_username },
1086 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_DATATYPE,                "JOB_NOTIFY_DATATYPE",                POINTER,   spoolss_notify_datatype },
1087 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_PRINT_PROCESSOR,         "JOB_NOTIFY_PRINT_PROCESSOR",         POINTER,   spoolss_notify_print_processor },
1088 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_PARAMETERS,              "JOB_NOTIFY_PARAMETERS",              POINTER,   spoolss_notify_parameters },
1089 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_DRIVER_NAME,             "JOB_NOTIFY_DRIVER_NAME",             POINTER,   spoolss_notify_driver_name },
1090 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_DEVMODE,                 "JOB_NOTIFY_DEVMODE",                 POINTER,   spoolss_notify_devmode },
1091 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_STATUS,                  "JOB_NOTIFY_STATUS",                  ONE_VALUE, spoolss_notify_job_status },
1092 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_STATUS_STRING,           "JOB_NOTIFY_STATUS_STRING",           POINTER,   spoolss_notify_job_status_string },
1093 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_SECURITY_DESCRIPTOR,     "JOB_NOTIFY_SECURITY_DESCRIPTOR",     POINTER,   NULL },
1094 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_DOCUMENT,                "JOB_NOTIFY_DOCUMENT",                POINTER,   spoolss_notify_job_name },
1095 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_PRIORITY,                "JOB_NOTIFY_PRIORITY",                ONE_VALUE, spoolss_notify_priority },
1096 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_POSITION,                "JOB_NOTIFY_POSITION",                ONE_VALUE, spoolss_notify_job_position },
1097 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_SUBMITTED,               "JOB_NOTIFY_SUBMITTED",               POINTER,   NULL },
1098 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_START_TIME,              "JOB_NOTIFY_START_TIME",              ONE_VALUE, spoolss_notify_start_time },
1099 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_UNTIL_TIME,              "JOB_NOTIFY_UNTIL_TIME",              ONE_VALUE, spoolss_notify_until_time },
1100 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_TIME,                    "JOB_NOTIFY_TIME",                    ONE_VALUE, spoolss_notify_job_time },
1101 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_TOTAL_PAGES,             "JOB_NOTIFY_TOTAL_PAGES",             ONE_VALUE, NULL },
1102 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_PAGES_PRINTED,           "JOB_NOTIFY_PAGES_PRINTED",           ONE_VALUE, NULL },
1103 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_TOTAL_BYTES,             "JOB_NOTIFY_TOTAL_BYTES",             ONE_VALUE, spoolss_notify_job_size },
1104 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_BYTES_PRINTED,           "JOB_NOTIFY_BYTES_PRINTED",           ONE_VALUE, NULL },
1105 { END,                 END,                                "",                                   END,       NULL }
1106 };
1107
1108 /*******************************************************************
1109 return the size of info_data structure
1110 ********************************************************************/  
1111 uint32 size_of_notify_info_data(uint16 type, uint16 field)
1112 {
1113         int i=0;
1114
1115         while (notify_info_data_table[i].type != END)
1116         {
1117                 if ( (notify_info_data_table[i].type == type ) &&
1118                      (notify_info_data_table[i].field == field ) )
1119                 {
1120                         return (notify_info_data_table[i].size);
1121                         continue;
1122                 }
1123                 i++;
1124         }
1125         return (65535);
1126 }
1127
1128 /*******************************************************************
1129 return the type of notify_info_data
1130 ********************************************************************/  
1131 BOOL type_of_notify_info_data(uint16 type, uint16 field)
1132 {
1133         int i=0;
1134
1135         while (notify_info_data_table[i].type != END)
1136         {
1137                 if ( (notify_info_data_table[i].type == type ) &&
1138                      (notify_info_data_table[i].field == field ) )
1139                 {
1140                         if (notify_info_data_table[i].size == POINTER)
1141                         {
1142                                 return (False);
1143                         }
1144                         else
1145                         {
1146                                 return (True);
1147                         }
1148                         continue;
1149                 }
1150                 i++;
1151         }
1152         return (False);
1153 }
1154
1155 /****************************************************************************
1156 ****************************************************************************/
1157 static int search_notify(uint16 type, uint16 field, int *value)
1158 {       
1159         int j;
1160         BOOL found;
1161
1162         DEBUG(4,("\tsearch_notify: in\n"));     
1163         for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++)
1164         {
1165                 if ( (notify_info_data_table[j].type  == type  ) &&
1166                      (notify_info_data_table[j].field == field ) )
1167                 {
1168                         found=True;
1169                 }
1170         }
1171         *value=--j;
1172
1173         if ( found && (notify_info_data_table[j].fn != NULL) )
1174         {
1175                 DEBUG(4,("\tsearch_notify: out TRUE\n"));
1176                 return (True);
1177         }
1178         else
1179         {
1180                 DEBUG(4,("\tsearch_notify: out FALSE\n"));
1181                 return (False); 
1182         }
1183 }
1184
1185 /****************************************************************************
1186 ****************************************************************************/
1187 static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
1188 {
1189         DEBUG(4,("\tconstruct_info_data: in\n"));
1190         info_data->type     = type;
1191         info_data->field    = field;
1192         info_data->id       = id;
1193         info_data->size     = size_of_notify_info_data(type, field);
1194         info_data->enc_type = type_of_notify_info_data(type, field);
1195         DEBUG(4,("\tconstruct_info_data: out\n"));
1196 }
1197
1198
1199 /*******************************************************************
1200  *
1201  * fill a notify_info struct with info asked
1202  * 
1203  ********************************************************************/
1204 static void construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int pnum, 
1205                                           int snum, int i, uint32 id, connection_struct *conn)
1206 {
1207
1208         int k,j;
1209         uint16 type;
1210         uint16 field;
1211
1212         SPOOL_NOTIFY_INFO_DATA *info_data;
1213         print_queue_struct *queue=NULL;
1214         NT_PRINTER_INFO_LEVEL printer;
1215         
1216         DEBUG(4,("construct_notify_printer_info\n"));
1217         
1218         info_data=&(info->data[info->count]);
1219         
1220         type = Printer[pnum].notify_info[i].type;
1221
1222         DEBUGADD(4,("Notify number %d -> number of notify info: %d\n",i,Printer[pnum].notify_info[i].count));
1223         
1224         if (!get_a_printer(&printer, 2, lp_servicename(snum)))
1225         {
1226                 
1227                 for(k=0; k<Printer[pnum].notify_info[i].count; k++)
1228                 {
1229                         field = Printer[pnum].notify_info[i].fields[k];
1230                         DEBUGADD(4,("notify [%d]: type [%x], field [%x]\n", k, type, field));
1231
1232                         if (search_notify(type, field, &j) )
1233                         {
1234                                 DEBUGADD(4,("j=[%d]:%s\n", j, notify_info_data_table[j].name));
1235                                 construct_info_data(info_data, type, field, id);
1236                         
1237                                 DEBUGADD(4,("notify_info_data_table: in\n"));
1238                                 notify_info_data_table[j].fn(conn,snum, info_data, queue, &printer);
1239                                 DEBUGADD(4,("notify_info_data_table: out\n"));
1240                                 info->count++;
1241                                 info_data=&(info->data[info->count]);
1242                         }
1243                 }
1244         
1245                 free_a_printer(printer, 2);
1246         }
1247 }
1248
1249 /*******************************************************************
1250  *
1251  * fill a notify_info struct with info asked
1252  * 
1253  ********************************************************************/
1254 static void construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_INFO *info,
1255                                        int pnum, int snum, int i, uint32 id, connection_struct *conn)
1256 {
1257
1258         int k,j;
1259         uint16 type;
1260         uint16 field;
1261
1262         SPOOL_NOTIFY_INFO_DATA *info_data;
1263         NT_PRINTER_INFO_LEVEL printer;
1264         
1265         DEBUG(4,("construct_notify_jobs_info\n"));
1266         info_data=&(info->data[info->count]);
1267         
1268         type = Printer[pnum].notify_info[i].type;
1269
1270         DEBUGADD(4,("Notify number %d -> number of notify info: %d\n",i,Printer[pnum].notify_info[i].count));
1271
1272         if (!get_a_printer(&printer, 2, lp_servicename(snum)))
1273         {       
1274                 for(k=0; k<Printer[pnum].notify_info[i].count; k++)
1275                 {
1276                         field = Printer[pnum].notify_info[i].fields[k];
1277                         DEBUGADD(4,("notify [%d]: type [%x], field [%x]\n",k, type, field));
1278
1279                         if (search_notify(type, field, &j) )
1280                         {
1281                                 DEBUGADD(4,("j=[%d]:%s\n", j, notify_info_data_table[j].name));
1282                                 construct_info_data(info_data, type, field, id);
1283                                 DEBUGADD(4,("notify_info_data_table: in\n"));
1284                                 notify_info_data_table[j].fn(conn, snum, info_data, queue, &printer);
1285                                 DEBUGADD(4,("notify_info_data_table: out\n"));
1286                                 info->count++;
1287                                 info_data=&(info->data[info->count]);
1288                         }
1289                 }
1290                 free_a_printer(printer, 2);
1291         }
1292 }
1293
1294
1295 /*******************************************************************
1296  *
1297  * enumerate all printers on the printserver
1298  * fill a notify_info struct with info asked
1299  * 
1300  ********************************************************************/
1301 static void printserver_notify_info(PRINTER_HND *hnd, SPOOL_NOTIFY_INFO *info, connection_struct *conn)
1302 {
1303         int snum;
1304         int pnum=find_printer_index_by_hnd(hnd);
1305         int n_services=lp_numservices();
1306         int i=0;
1307         uint32 id=1;
1308         info->count=0;
1309
1310         DEBUG(4,("Enumerating printers\n"));
1311
1312         for (i=0; i<Printer[pnum].number_of_notify; i++)
1313         {
1314          if ( Printer[pnum].notify_info[i].type == PRINTER_NOTIFY_TYPE )
1315          {
1316           for (snum=0; snum<n_services; snum++)
1317           {
1318            if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
1319            {
1320                 construct_notify_printer_info(info, pnum, snum, i, id, conn);
1321                 id++;
1322            }
1323           }
1324          }
1325         }
1326         DEBUG(4,("All printers enumerated\n"));
1327 }
1328
1329 /*******************************************************************
1330  *
1331  * fill a notify_info struct with info asked
1332  * 
1333  ********************************************************************/
1334 static void printer_notify_info(PRINTER_HND *hnd, SPOOL_NOTIFY_INFO *info, connection_struct *conn)
1335 {
1336         int snum;
1337         int pnum=find_printer_index_by_hnd(hnd);
1338         int i=0, j;
1339         uint32 id=0xFFFF;
1340         
1341         info->count=0;
1342
1343         if (get_printer_snum(hnd, &snum) )
1344         {
1345                 for (i=0; i<Printer[pnum].number_of_notify; i++)
1346                 {
1347                  switch ( Printer[pnum].notify_info[i].type )
1348                  {
1349                   case PRINTER_NOTIFY_TYPE:
1350                    {
1351                         construct_notify_printer_info(info, pnum, snum, i, id, conn);
1352                         id--;
1353                         break;
1354                    }
1355                   case JOB_NOTIFY_TYPE:
1356                    {
1357                         int count;
1358                         print_queue_struct *queue=NULL;
1359                         print_status_struct status;
1360                         bzero(&status, sizeof(status)); 
1361                         count=get_printqueue(snum, conn, &queue, &status);
1362                         for (j=0; j<count; j++)
1363                         {
1364                                 construct_notify_jobs_info(&(queue[j]), info, pnum, snum, i, queue[j].job, conn);
1365                         }
1366                         if (queue) free(queue);
1367                         break;
1368                    }
1369                  }
1370                 }
1371         }
1372 }
1373
1374 /********************************************************************
1375  * api_spoolss_reply_rfnpcnex
1376  *
1377  * called from api_spoolss_rfnpcnex (see this to understand)
1378  ********************************************************************/
1379 static void spoolss_reply_rfnpcnex(SPOOL_Q_RFNPCNEX *q_u, prs_struct *rdata, connection_struct *conn)
1380 {
1381         SPOOL_R_RFNPCNEX r_u;
1382         int pnum=find_printer_index_by_hnd(&(q_u->handle));
1383
1384         if (OPEN_HANDLE(pnum))
1385         {
1386                 DEBUG(4,("Printer %x of type %x\n",pnum,Printer[pnum].printer_type));
1387                 switch (Printer[pnum].printer_type)
1388                 {
1389                 case PRINTER_HANDLE_IS_PRINTSERVER:
1390                         printserver_notify_info(&(q_u->handle), &(r_u.info), conn);
1391                         break;
1392                 case PRINTER_HANDLE_IS_PRINTER:
1393                         printer_notify_info(&(q_u->handle), &(r_u.info), conn);
1394                         break;
1395                 }
1396                 
1397                 spoolss_io_r_rfnpcnex("", &r_u, rdata, 0);
1398         }
1399 }
1400
1401 /********************************************************************
1402  * api_spoolss_rfnpcnex
1403  * ReplyFindNextPrinterChangeNotifyEx
1404  * called from the spoolss dispatcher
1405  *
1406  ********************************************************************/
1407 static void api_spoolss_rfnpcnex(pipes_struct *p, prs_struct *data, 
1408                                   prs_struct *rdata)
1409 {
1410         SPOOL_Q_RFNPCNEX q_u;
1411
1412         spoolss_io_q_rfnpcnex("", &q_u, data, 0);
1413
1414         spoolss_reply_rfnpcnex(&q_u, rdata, p->conn);
1415 }
1416
1417 /********************************************************************
1418  * construct_printer_info_0
1419  * fill a printer_info_1 struct
1420  ********************************************************************/
1421 static void construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring servername, connection_struct *conn)
1422 {
1423         pstring chaine;
1424         int count;
1425         
1426         print_queue_struct *queue=NULL;
1427         print_status_struct status;
1428         bzero(&status,sizeof(status));  
1429         count=get_printqueue(snum, conn ,&queue,&status);
1430         
1431         /* the description and the name are of the form \\server\share */
1432         slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s",servername, lp_servicename(snum));
1433                                                             
1434         make_unistr(&(printer->printername), chaine);
1435         
1436         slprintf(chaine,sizeof(chaine)-1,"\\\\%s", servername);
1437         make_unistr(&(printer->servername), chaine);
1438         
1439         printer->cjobs = count;
1440         printer->attributes =   PRINTER_ATTRIBUTE_SHARED   \
1441                               | PRINTER_ATTRIBUTE_NETWORK  \
1442                               | PRINTER_ATTRIBUTE_RAW_ONLY ;
1443         printer->unknown0     = 0x1; /* pointer */
1444         printer->unknown1     = 0x000A07CE; /* don't known */
1445         printer->unknown2     = 0x00020005;
1446         printer->unknown3     = 0x0006000D;
1447         printer->unknown4     = 0x02180026;
1448         printer->unknown5     = 0x09;
1449         printer->unknown6     = 0x36;
1450         printer->majorversion = 0x0004; /* NT 4 */
1451         printer->buildversion = 0x0565; /* build 1381 */
1452         printer->unknown7     = 0x1;
1453         printer->unknown8     = 0x0;
1454         printer->unknown9     = 0x2;
1455         printer->unknown10    = 0x3;
1456         printer->unknown11    = 0x0;
1457         printer->unknown12    = 0x0;
1458         printer->unknown13    = 0x0;
1459         printer->unknown14    = 0x1;
1460         printer->unknown15    = 0x024a; /*586 Pentium ? */
1461         printer->unknown16    = 0x0;
1462         printer->unknown17    = 0x423ed444;
1463         printer->unknown18    = 0x0;
1464         printer->status       = status.status;
1465         printer->unknown20    = 0x0;
1466         printer->unknown21    = 0x0648;
1467         printer->unknown22    = 0x0;
1468         printer->unknown23    = 0x5;
1469         if (queue) free(queue);
1470         
1471 }
1472
1473 /********************************************************************
1474  * construct_printer_info_1
1475  * fill a printer_info_1 struct
1476  ********************************************************************/
1477 static BOOL construct_printer_info_1(PRINTER_INFO_1 *printer,int snum, pstring servername, connection_struct *conn)
1478 {
1479         pstring chaine;
1480         NT_PRINTER_INFO_LEVEL ntprinter;
1481         
1482         if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
1483         {
1484                 return (False);
1485         }
1486         
1487         printer->flags=PRINTER_ENUM_NAME;
1488
1489         /* the description and the name are of the form \\server\share */
1490         slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s,%s,%s",servername,
1491                                                             ntprinter.info_2->printername,
1492                                                             ntprinter.info_2->drivername,
1493                                                             lp_comment(snum));
1494         make_unistr(&(printer->description), chaine);
1495         
1496         slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s", servername, ntprinter.info_2->printername);
1497         make_unistr(&(printer->name), chaine);
1498         
1499         make_unistr(&(printer->comment), lp_comment(snum));
1500         
1501         free_a_printer(ntprinter, 2);
1502         return (True);
1503 }
1504
1505 /****************************************************************************
1506 ****************************************************************************/
1507 static void construct_dev_mode(DEVICEMODE *devmode, int snum, char *servername)
1508 {
1509         char adevice[32];
1510         char aform[32];
1511         NT_PRINTER_INFO_LEVEL printer;  
1512         NT_DEVICEMODE *ntdevmode;
1513
1514         DEBUG(7,("construct_dev_mode\n"));
1515         
1516         bzero(&(devmode->devicename), 2*sizeof(adevice));
1517         bzero(&(devmode->formname), 2*sizeof(aform));
1518
1519         DEBUGADD(8,("getting printer characteristics\n"));
1520
1521         get_a_printer(&printer, 2, lp_servicename(snum));
1522         ntdevmode=(printer.info_2)->devmode;
1523
1524         DEBUGADD(8,("loading DEVICEMODE\n"));
1525         snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, 
1526                                                          printer.info_2->printername);
1527         make_unistr(&(devmode->devicename), adevice);
1528
1529         snprintf(aform, sizeof(aform), ntdevmode->formname);
1530         make_unistr(&(devmode->formname), aform);
1531
1532         devmode->specversion      = ntdevmode->specversion;
1533         devmode->driverversion    = ntdevmode->driverversion;
1534         devmode->size             = ntdevmode->size;
1535         devmode->driverextra      = ntdevmode->driverextra;
1536         devmode->fields           = ntdevmode->fields;
1537                                     
1538         devmode->orientation      = ntdevmode->orientation;     
1539         devmode->papersize        = ntdevmode->papersize;
1540         devmode->paperlength      = ntdevmode->paperlength;
1541         devmode->paperwidth       = ntdevmode->paperwidth;
1542         devmode->scale            = ntdevmode->scale;
1543         devmode->copies           = ntdevmode->copies;
1544         devmode->defaultsource    = ntdevmode->defaultsource;
1545         devmode->printquality     = ntdevmode->printquality;
1546         devmode->color            = ntdevmode->color;
1547         devmode->duplex           = ntdevmode->duplex;
1548         devmode->yresolution      = ntdevmode->yresolution;
1549         devmode->ttoption         = ntdevmode->ttoption;
1550         devmode->collate          = ntdevmode->collate;
1551         devmode->icmmethod        = ntdevmode->icmmethod;
1552         devmode->icmintent        = ntdevmode->icmintent;
1553         devmode->mediatype        = ntdevmode->mediatype;
1554         devmode->dithertype       = ntdevmode->dithertype;
1555
1556         if (ntdevmode->private != NULL)
1557         {
1558                 devmode->private=(uint8 *)malloc(devmode->driverextra*sizeof(uint8));
1559                 memcpy(devmode->private, ntdevmode->private, devmode->driverextra);
1560         }
1561
1562         free_a_printer(printer, 2);
1563 }
1564
1565 /********************************************************************
1566  * construct_printer_info_2
1567  * fill a printer_info_2 struct
1568  ********************************************************************/
1569 static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring servername, connection_struct *conn)
1570 {
1571         pstring chaine;
1572         int count;
1573         DEVICEMODE *devmode;
1574         NT_PRINTER_INFO_LEVEL ntprinter;
1575         
1576         print_queue_struct *queue=NULL;
1577         print_status_struct status;
1578         bzero(&status, sizeof(status)); 
1579         count=get_printqueue(snum, conn, &queue, &status);
1580
1581         if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
1582         {
1583                 return (False);
1584         }       
1585
1586         snprintf(chaine, sizeof(chaine)-1, "\\\\%s", servername);
1587         make_unistr(&(printer->servername), chaine);                    /* servername*/
1588         
1589         snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", servername, ntprinter.info_2->printername);
1590         make_unistr(&(printer->printername), chaine);                   /* printername*/
1591
1592         make_unistr(&(printer->sharename),      lp_servicename(snum));  /* sharename */
1593
1594         make_unistr(&(printer->portname),       lp_servicename(snum));          /* port */      
1595         make_unistr(&(printer->drivername),     ntprinter.info_2->drivername);  /* drivername */
1596                 
1597         make_unistr(&(printer->comment),        ntprinter.info_2->comment);     /* comment */   
1598         make_unistr(&(printer->location),       ntprinter.info_2->location);    /* location */  
1599         make_unistr(&(printer->sepfile),        ntprinter.info_2->sepfile);     /* separator file */
1600         make_unistr(&(printer->printprocessor), ntprinter.info_2->printprocessor);/* print processor */
1601         make_unistr(&(printer->datatype),       ntprinter.info_2->datatype);    /* datatype */  
1602         make_unistr(&(printer->parameters),     ntprinter.info_2->parameters);  /* parameters (of print processor) */   
1603
1604         printer->attributes =   PRINTER_ATTRIBUTE_SHARED   \
1605                               | PRINTER_ATTRIBUTE_NETWORK  \
1606                               | PRINTER_ATTRIBUTE_RAW_ONLY ;            /* attributes */
1607
1608         printer->priority        = ntprinter.info_2->priority;          /* priority */  
1609         printer->defaultpriority = ntprinter.info_2->default_priority;  /* default priority */
1610         printer->starttime       = ntprinter.info_2->starttime;         /* starttime */
1611         printer->untiltime       = ntprinter.info_2->untiltime;         /* untiltime */
1612         printer->status          = status.status;                       /* status */
1613         printer->cjobs           = count;                               /* jobs */
1614         printer->averageppm      = ntprinter.info_2->averageppm;        /* average pages per minute */
1615                         
1616         devmode=(DEVICEMODE *)malloc(sizeof(DEVICEMODE));
1617         ZERO_STRUCTP(devmode);  
1618         construct_dev_mode(devmode, snum, servername);                  
1619         printer->devmode=devmode;
1620         
1621         if (queue) free(queue);
1622         free_a_printer(ntprinter, 2);
1623         return (True);
1624 }
1625
1626 /********************************************************************
1627  * enum_printer_info_1
1628  * glue between spoolss_reply_enumprinters and construct_printer_info_1
1629  ********************************************************************/
1630 static BOOL enum_printer_info_1(PRINTER_INFO_1 **printer, int snum, int number, connection_struct *conn)
1631 {
1632         pstring servername;
1633
1634         *printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1));
1635         DEBUG(4,("Allocated memory for ONE PRINTER_INFO_1 at [%p]\n", *printer));       
1636         pstrcpy(servername, global_myname);
1637         if (!construct_printer_info_1(*printer, snum, servername, conn))
1638         {
1639                 free(*printer);
1640                 return (False);
1641         }
1642         else
1643         {
1644                 return (True);
1645         }
1646 }
1647
1648 /********************************************************************
1649  * enum_printer_info_2
1650  * glue between spoolss_reply_enumprinters and construct_printer_info_2
1651  ********************************************************************/
1652 static BOOL enum_printer_info_2(PRINTER_INFO_2 **printer, int snum, int number, connection_struct *conn)
1653 {
1654         pstring servername;
1655
1656         *printer=(PRINTER_INFO_2 *)malloc(sizeof(PRINTER_INFO_2));
1657         DEBUG(4,("Allocated memory for ONE PRINTER_INFO_2 at [%p]\n", *printer));       
1658         pstrcpy(servername, global_myname);
1659         if (!construct_printer_info_2(*printer, snum, servername, conn))
1660         {
1661                 free(*printer);
1662                 return (False);
1663         }
1664         else
1665         {
1666                 return (True);
1667         }
1668 }
1669
1670 /********************************************************************
1671  * api_spoolss_reply_enumprinters
1672  *
1673  * called from api_spoolss_enumprinters (see this to understand)
1674  ********************************************************************/
1675 static void enum_all_printers_info_1(PRINTER_INFO_1 ***printers, uint32 *number, connection_struct *conn)
1676 {
1677         int snum;
1678         int n_services=lp_numservices();
1679         *printers=NULL;
1680         *number=0;
1681
1682         for (snum=0;snum<n_services; snum++)
1683         {
1684                 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
1685                 {
1686                         DEBUG(4,("Found a printer: %s[%x]\n",lp_servicename(snum),snum));
1687                         *printers=Realloc(*printers, (*number+1)*sizeof(PRINTER_INFO_1 *));                     
1688                         DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1 pointers at [%p]\n", *number+1, *printers));         
1689                         if (enum_printer_info_1( &((*printers)[*number]), snum, *number, conn) )
1690                         {                       
1691                                 (*number)++;
1692                         }
1693                 }
1694         }
1695 }
1696
1697 /********************************************************************
1698  * api_spoolss_reply_enumprinters
1699  *
1700  * called from api_spoolss_enumprinters (see this to understand)
1701  ********************************************************************/
1702 static void enum_all_printers_info_2(PRINTER_INFO_2 ***printers, uint32 *number, connection_struct *conn)
1703 {
1704         int snum;
1705         int n_services=lp_numservices();
1706         *printers=NULL;
1707         *number=0;
1708
1709         for (snum=0;snum<n_services; snum++)
1710         {
1711                 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
1712                 {
1713                         DEBUG(4,("Found a printer: %s[%x]\n",lp_servicename(snum),snum));
1714                         *printers=Realloc(*printers, (*number+1)*sizeof(PRINTER_INFO_2 *));                     
1715                         DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1 pointers at [%p]\n", *number+1, *printers));                 
1716                         if (enum_printer_info_2( &((*printers)[*number]), snum, *number, conn) )
1717                         {                       
1718                                 (*number)++;
1719                         }
1720                 }
1721         }
1722 }
1723
1724 /****************************************************************************
1725 ****************************************************************************/
1726 static void free_enum_printers_info_1(PRINTER_INFO_1 **printers, uint32 total)
1727 {
1728         int number=0;   
1729         if (printers != NULL)
1730         {                       
1731                 for (number=0; number<total; number++)
1732                 {
1733                         if (printers[number] != NULL)
1734                         {
1735                                 free(printers[number]);
1736                         }
1737                 }
1738                 free(printers);
1739         }
1740 }
1741
1742 /****************************************************************************
1743 ****************************************************************************/
1744 static void free_enum_printers_info_2(PRINTER_INFO_2 **printers, uint32 total)
1745 {
1746         int number=0;           
1747         if (printers != NULL)
1748         {       
1749                 for (number=0; number<total; number++)
1750                 {               
1751                         if (printers[number] != NULL)
1752                         {
1753                                 free(printers[number]->devmode);
1754                                 free(printers[number]);
1755                         }
1756                 }
1757                 free(printers);
1758         }
1759 }
1760
1761 /****************************************************************************
1762 ****************************************************************************/
1763 static void free_enum_printers_info(SPOOL_R_ENUMPRINTERS *r_u)
1764 {       
1765         DEBUG(4,("free_enum_printers_info: [%d] structs to free at level [%d]\n", r_u->returned, r_u->level));
1766         switch (r_u->level)
1767         {
1768                 case 1:                 
1769                         free_enum_printers_info_1(r_u->printer.printers_1, r_u->returned);
1770                         break;
1771                 case 2:
1772                         free_enum_printers_info_2(r_u->printer.printers_2, r_u->returned);
1773                         break;
1774         }
1775 }
1776
1777 /********************************************************************
1778  * api_spoolss_reply_enumprinters
1779  *
1780  * called from api_spoolss_enumprinters (see this to understand)
1781  ********************************************************************/
1782 static void spoolss_reply_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *rdata, connection_struct *conn)
1783 {
1784         SPOOL_R_ENUMPRINTERS r_u;
1785         
1786         DEBUG(4,("Enumerating printers\n"));
1787
1788         memcpy(r_u.servername.buffer,q_u->servername.buffer,2*q_u->servername.uni_str_len);
1789         r_u.servername.buffer[q_u->servername.uni_str_len]=0x0000;
1790         r_u.returned=0;
1791
1792         switch (q_u->level)
1793         {
1794                 case 1:
1795                         if ( (q_u->flags==PRINTER_ENUM_NAME) || (q_u->flags==PRINTER_ENUM_NETWORK) )
1796                                 /*if (is_a_printerserver(q_u->servername))*/
1797                                         enum_all_printers_info_1(&(r_u.printer.printers_1), &(r_u.returned), conn );
1798                                 /*else  
1799                                         enum_one_printer_info_1(&r_u);*/
1800                         break;
1801                 case 2:
1802                         if ( (q_u->flags==PRINTER_ENUM_NAME) || (q_u->flags==PRINTER_ENUM_NETWORK) )
1803                                 /*if (is_a_printerserver(q_u->servername))*/
1804                                         enum_all_printers_info_2(&(r_u.printer.printers_2), &(r_u.returned), conn );
1805                                 /*else  
1806                                         enum_one_printer_info_2(&r_u);*/
1807                         break;
1808                 case 3:         /* doesn't exist */
1809                         break;
1810                 case 4:         /* can't, always on local machine */
1811                         break;
1812                 case 5:
1813                         break;
1814                         
1815         }
1816         DEBUG(4,("%d printers enumerated\n", r_u.returned));
1817         r_u.offered=q_u->buffer.size;
1818         r_u.level=q_u->level;
1819         r_u.status=0x0000;
1820
1821         spoolss_io_r_enumprinters("",&r_u,rdata,0);
1822         free_enum_printers_info(&r_u);
1823 }
1824
1825 /********************************************************************
1826  * api_spoolss_enumprinters
1827  * called from the spoolss dispatcher
1828  *
1829  ********************************************************************/
1830 static void api_spoolss_enumprinters(pipes_struct *p, prs_struct *data, 
1831                                      prs_struct *rdata)
1832 {
1833         SPOOL_Q_ENUMPRINTERS q_u;
1834
1835         spoolss_io_q_enumprinters("", &q_u, data, 0);
1836
1837         spoolss_reply_enumprinters(&q_u, rdata, p->conn);
1838         
1839         spoolss_io_free_buffer(&(q_u.buffer));
1840 }
1841
1842
1843 /****************************************************************************
1844 ****************************************************************************/
1845 static void spoolss_reply_getprinter(SPOOL_Q_GETPRINTER *q_u, prs_struct *rdata, connection_struct *conn)
1846 {
1847         SPOOL_R_GETPRINTER r_u;
1848         int snum;
1849         pstring servername;
1850         
1851         pstrcpy(servername, global_myname);
1852
1853         get_printer_snum(&(q_u->handle),&snum);
1854         
1855         switch (q_u->level)
1856         {
1857                 case 0:
1858                 { 
1859                         PRINTER_INFO_0 *printer;
1860                         
1861                         printer=(PRINTER_INFO_0 *)malloc(sizeof(PRINTER_INFO_0));
1862                         
1863                         construct_printer_info_0(printer, snum, servername, conn);
1864                         r_u.printer.info0=printer;
1865                         r_u.status=0x0000;
1866                         r_u.offered=q_u->offered;
1867                         r_u.level=q_u->level;
1868                         
1869                         spoolss_io_r_getprinter("",&r_u,rdata,0);
1870                         
1871                         free(printer);
1872                         
1873                         break;
1874                 }
1875                 case 1:
1876                 {
1877                         PRINTER_INFO_1 *printer;
1878                         
1879                         printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1));
1880
1881                         construct_printer_info_1(printer, snum, servername, conn);
1882
1883                         r_u.printer.info1=printer;                      
1884                         r_u.status=0x0000;
1885                         r_u.offered=q_u->offered;
1886                         r_u.level=q_u->level;
1887                         spoolss_io_r_getprinter("",&r_u,rdata,0);
1888                         
1889                         free(printer);
1890                                 
1891                         break;
1892                 }
1893                 case 2:
1894                 {
1895                         PRINTER_INFO_2 *printer;
1896                         
1897                         printer=(PRINTER_INFO_2 *)malloc(sizeof(PRINTER_INFO_2));       
1898                         construct_printer_info_2(printer, snum, servername, conn);
1899                         
1900                         r_u.printer.info2=printer;      
1901                         r_u.status=0x0000;
1902                         r_u.offered=q_u->offered;
1903                         r_u.level=q_u->level;
1904                         spoolss_io_r_getprinter("",&r_u,rdata,0);
1905                         
1906                         free(printer->devmode);
1907                         free(printer);
1908                                 
1909                         break;
1910                 }
1911         }
1912 }
1913
1914 /********************************************************************
1915  * api_spoolss_getprinter
1916  * called from the spoolss dispatcher
1917  *
1918  ********************************************************************/
1919 static void api_spoolss_getprinter(pipes_struct *p, prs_struct *data, 
1920                                    prs_struct *rdata)
1921 {
1922         SPOOL_Q_GETPRINTER q_u;
1923         
1924         spoolss_io_q_getprinter("", &q_u, data, 0);
1925
1926         spoolss_reply_getprinter(&q_u, rdata, p->conn);
1927 }
1928
1929 /********************************************************************
1930  * construct_printer_driver_info_1
1931  * fill a construct_printer_driver_info_1 struct
1932  ********************************************************************/
1933 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, 
1934                                        NT_PRINTER_DRIVER_INFO_LEVEL driver, 
1935                                        pstring servername, fstring architecture)
1936 {
1937         make_unistr( &(info->name), driver.info_3->name);
1938 }
1939
1940 static void construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, 
1941                                             pstring servername, fstring architecture)
1942 {       
1943         NT_PRINTER_INFO_LEVEL printer;
1944         NT_PRINTER_DRIVER_INFO_LEVEL driver;
1945
1946         get_a_printer(&printer, 2, lp_servicename(snum) );
1947         get_a_printer_driver(&driver, 3, printer.info_2->drivername, architecture);     
1948         
1949         fill_printer_driver_info_1(info, driver, servername, architecture);
1950         
1951         free_a_printer_driver(driver, 3);
1952         free_a_printer(printer, 2);
1953 }
1954
1955 /********************************************************************
1956  * construct_printer_driver_info_2
1957  * fill a printer_info_2 struct
1958  ********************************************************************/
1959 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, 
1960                                        NT_PRINTER_DRIVER_INFO_LEVEL driver, 
1961                                        pstring servername, fstring architecture)
1962 {
1963         pstring where;
1964         pstring temp_driverpath;
1965         pstring temp_datafile;
1966         pstring temp_configfile;
1967         fstring short_archi;
1968
1969         get_short_archi(short_archi,architecture);
1970         
1971         snprintf(where,sizeof(where)-1,"\\\\%s\\print$\\%s\\", servername, short_archi);
1972
1973         info->version=driver.info_3->cversion;
1974
1975         make_unistr( &(info->name),         driver.info_3->name );
1976         make_unistr( &(info->architecture), architecture );
1977         
1978         snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "%s%s", where, 
1979                  driver.info_3->driverpath);
1980         make_unistr( &(info->driverpath),   temp_driverpath );
1981
1982         snprintf(temp_datafile,   sizeof(temp_driverpath)-1, "%s%s", where, 
1983                  driver.info_3->datafile);
1984         make_unistr( &(info->datafile),     temp_datafile );
1985
1986         snprintf(temp_configfile, sizeof(temp_driverpath)-1, "%s%s", where, 
1987                  driver.info_3->configfile);
1988         make_unistr( &(info->configfile),   temp_configfile );  
1989 }
1990
1991 /********************************************************************
1992  * construct_printer_driver_info_2
1993  * fill a printer_info_2 struct
1994  ********************************************************************/
1995 static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, 
1996                                             pstring servername, fstring architecture)
1997 {
1998         NT_PRINTER_INFO_LEVEL printer;
1999         NT_PRINTER_DRIVER_INFO_LEVEL driver;
2000         
2001         get_a_printer(&printer, 2, lp_servicename(snum) );
2002         get_a_printer_driver(&driver, 3, printer.info_2->drivername, architecture);     
2003
2004         fill_printer_driver_info_2(info, driver, servername, architecture);
2005
2006         free_a_printer_driver(driver, 3);
2007         free_a_printer(printer, 2);
2008 }
2009
2010 /********************************************************************
2011  * construct_printer_info_3
2012  * fill a printer_info_3 struct
2013  ********************************************************************/
2014 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, 
2015                                        NT_PRINTER_DRIVER_INFO_LEVEL driver, 
2016                                        pstring servername, fstring architecture)
2017 {
2018         pstring where;
2019         pstring temp_driverpath;
2020         pstring temp_datafile;
2021         pstring temp_configfile;
2022         pstring temp_helpfile;
2023         fstring short_archi;
2024         
2025         get_short_archi(short_archi, architecture);
2026         
2027         snprintf(where,sizeof(where)-1,"\\\\%s\\print$\\%s\\", servername, short_archi);
2028         
2029         info->version=driver.info_3->cversion;
2030
2031         make_unistr( &(info->name),         driver.info_3->name );      
2032         make_unistr( &(info->architecture), architecture );
2033         
2034         snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "%s%s", where, driver.info_3->driverpath);          
2035         make_unistr( &(info->driverpath), temp_driverpath );
2036         
2037         snprintf(temp_datafile,   sizeof(temp_datafile)-1,   "%s%s", where, driver.info_3->datafile); 
2038         make_unistr( &(info->datafile), temp_datafile );
2039         
2040         snprintf(temp_configfile, sizeof(temp_configfile)-1, "%s%s", where, driver.info_3->configfile);
2041         make_unistr( &(info->configfile), temp_configfile );    
2042         
2043         snprintf(temp_helpfile,   sizeof(temp_helpfile)-1,   "%s%s", where, driver.info_3->helpfile);
2044         make_unistr( &(info->helpfile), temp_helpfile );
2045
2046         make_unistr( &(info->monitorname), driver.info_3->monitorname );        
2047         make_unistr( &(info->defaultdatatype), driver.info_3->defaultdatatype );
2048
2049         make_unistr( &(info->dependentfiles), "" );
2050 }
2051
2052 /********************************************************************
2053  * construct_printer_info_3
2054  * fill a printer_info_3 struct
2055  ********************************************************************/
2056 static void construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, 
2057                                             pstring servername, fstring architecture)
2058 {       
2059         NT_PRINTER_INFO_LEVEL printer;
2060         NT_PRINTER_DRIVER_INFO_LEVEL driver;
2061         
2062         get_a_printer(&printer, 2, lp_servicename(snum) );      
2063         get_a_printer_driver(&driver, 3, printer.info_2->drivername, architecture);     
2064
2065         fill_printer_driver_info_3(info, driver, servername, architecture);
2066
2067         free_a_printer_driver(driver, 3);
2068         free_a_printer(printer, 2);
2069 }
2070
2071 /****************************************************************************
2072 ****************************************************************************/
2073 static void spoolss_reply_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *rdata)
2074 {
2075         SPOOL_R_GETPRINTERDRIVER2 r_u;
2076         pstring servername;
2077         fstring architecture;
2078         int snum;
2079         DRIVER_INFO_1 *info1=NULL;
2080         DRIVER_INFO_2 *info2=NULL;
2081         DRIVER_INFO_3 *info3=NULL;
2082
2083         pstrcpy(servername, global_myname);
2084         get_printer_snum(&(q_u->handle),&snum);
2085
2086         r_u.offered=q_u->buf_size;
2087         r_u.level=q_u->level;
2088         r_u.status=0x0000;      
2089         
2090         unistr2_to_ascii(architecture, &(q_u->architecture), sizeof(architecture) );
2091         
2092         DEBUG(1,("spoolss_reply_getprinterdriver2:[%d]\n", q_u->level));
2093         
2094         switch (q_u->level)
2095         {
2096                 case 1:
2097                 {                       
2098                         info1=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1));
2099                         construct_printer_driver_info_1(info1, snum, servername, architecture);
2100                         r_u.printer.info1=info1;                        
2101                         break;                  
2102                 }
2103                 case 2:
2104                 {
2105                         info2=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2));
2106                         construct_printer_driver_info_2(info2, snum, servername, architecture);
2107                         r_u.printer.info2=info2;                        
2108                         break;
2109                 }
2110                 case 3:
2111                 {
2112                         info3=(DRIVER_INFO_3 *)malloc(sizeof(DRIVER_INFO_3));
2113                         construct_printer_driver_info_3(info3, snum, servername, architecture);
2114                         r_u.printer.info3=info3;
2115                         break;
2116                 }
2117         }
2118         
2119         spoolss_io_r_getprinterdriver2("",&r_u,rdata,0);
2120         
2121         if (info1!=NULL) free(info1);
2122         if (info2!=NULL) free(info2);
2123         if (info3!=NULL) free(info3);
2124         
2125 }
2126
2127 /********************************************************************
2128  * api_spoolss_getprinter
2129  * called from the spoolss dispatcher
2130  *
2131  ********************************************************************/
2132 static void api_spoolss_getprinterdriver2(pipes_struct *p, prs_struct *data,
2133                                           prs_struct *rdata)
2134 {
2135         SPOOL_Q_GETPRINTERDRIVER2 q_u;
2136         
2137         spoolss_io_q_getprinterdriver2("", &q_u, data, 0);
2138         
2139         spoolss_reply_getprinterdriver2(&q_u, rdata);
2140         
2141         spoolss_io_free_buffer(&(q_u.buffer));
2142 }
2143
2144 /****************************************************************************
2145 ****************************************************************************/
2146 static void spoolss_reply_startpageprinter(SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *rdata)
2147 {
2148         SPOOL_R_STARTPAGEPRINTER r_u;
2149         int pnum = find_printer_index_by_hnd(&(q_u->handle));
2150
2151         if (OPEN_HANDLE(pnum))
2152         {
2153                 Printer[pnum].page_started=True;
2154                 r_u.status=0x0;
2155
2156                 spoolss_io_r_startpageprinter("",&r_u,rdata,0);         
2157         }
2158         else
2159         {
2160                 DEBUG(3,("Error in startpageprinter printer handle (pnum=%x)\n",pnum));
2161         }
2162 }
2163
2164 /********************************************************************
2165  * api_spoolss_getprinter
2166  * called from the spoolss dispatcher
2167  *
2168  ********************************************************************/
2169 static void api_spoolss_startpageprinter(pipes_struct *p, prs_struct *data,
2170                                           prs_struct *rdata)
2171 {
2172         SPOOL_Q_STARTPAGEPRINTER q_u;
2173         
2174         spoolss_io_q_startpageprinter("", &q_u, data, 0);
2175         
2176         spoolss_reply_startpageprinter(&q_u, rdata);
2177 }
2178
2179 /****************************************************************************
2180 ****************************************************************************/
2181 static void spoolss_reply_endpageprinter(SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *rdata)
2182 {
2183         SPOOL_R_ENDPAGEPRINTER r_u;
2184         int pnum = find_printer_index_by_hnd(&(q_u->handle));
2185
2186         if (OPEN_HANDLE(pnum))
2187         {
2188                 Printer[pnum].page_started=False;
2189                 r_u.status=0x0;
2190
2191                 spoolss_io_r_endpageprinter("",&r_u,rdata,0);           
2192         }
2193         else
2194         {
2195                 DEBUG(3,("Error in endpageprinter printer handle (pnum=%x)\n",pnum));
2196         }
2197 }
2198
2199 /********************************************************************
2200  * api_spoolss_getprinter
2201  * called from the spoolss dispatcher
2202  *
2203  ********************************************************************/
2204 static void api_spoolss_endpageprinter(pipes_struct *p, prs_struct *data,
2205                                           prs_struct *rdata)
2206 {
2207         SPOOL_Q_ENDPAGEPRINTER q_u;
2208         
2209         spoolss_io_q_endpageprinter("", &q_u, data, 0);
2210         
2211         spoolss_reply_endpageprinter(&q_u, rdata);
2212 }
2213
2214 /****************************************************************************
2215 ****************************************************************************/
2216 static void spoolss_reply_startdocprinter(SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *rdata)
2217 {
2218         SPOOL_R_STARTDOCPRINTER r_u;
2219         int pnum = find_printer_index_by_hnd(&(q_u->handle));
2220
2221         if (OPEN_HANDLE(pnum))
2222         {               
2223                 r_u.jobid=Printer[pnum].current_jobid;
2224                 r_u.status=0x0;
2225
2226                 spoolss_io_r_startdocprinter("",&r_u,rdata,0);          
2227         }
2228         else
2229         {
2230                 DEBUG(3,("Error in startdocprinter printer handle (pnum=%x)\n",pnum));
2231         }
2232 }
2233
2234 /********************************************************************
2235  * api_spoolss_getprinter
2236  * called from the spoolss dispatcher
2237  *
2238  ********************************************************************/
2239 static void api_spoolss_startdocprinter(pipes_struct *p, prs_struct *data,
2240                                           prs_struct *rdata)
2241 {
2242         SPOOL_Q_STARTDOCPRINTER q_u;
2243         pstring fname;
2244         pstring tempname;
2245         int fd = -1;
2246         int snum;
2247         int pnum;
2248
2249         /* decode the stream and fill the struct */
2250         spoolss_io_q_startdocprinter("", &q_u, data, 0);
2251         
2252         pnum = find_printer_index_by_hnd(&(q_u.handle));
2253
2254         if (OPEN_HANDLE(pnum))
2255         {
2256                 /* get the share number of the printer */
2257                 get_printer_snum(&(q_u.handle),&snum);
2258
2259                 /* Create a temporary file in the printer spool directory
2260                  * and open it
2261                  */
2262
2263                 slprintf(tempname,sizeof(tempname)-1, "%s/smb_print.XXXXXX",lp_pathname(snum));  
2264                 pstrcpy(fname, (char *)mktemp(tempname));
2265
2266                 fd=open(fname, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
2267                 DEBUG(4,("Temp spool file created: [%s]\n", fname));
2268
2269                 Printer[pnum].current_jobid=fd;
2270                 pstrcpy(Printer[pnum].document_name,fname);
2271                 
2272                 unistr2_to_ascii(Printer[pnum].job_name, 
2273                                  &(q_u.doc_info_container.docinfo.doc_info_1.docname), 
2274                                  sizeof(Printer[pnum].job_name));
2275                 
2276                 Printer[pnum].document_fd=fd;
2277                 Printer[pnum].document_started=True;
2278         }       
2279         spoolss_reply_startdocprinter(&q_u, rdata);
2280 }
2281
2282 /****************************************************************************
2283 ****************************************************************************/
2284 static void spoolss_reply_enddocprinter(SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *rdata)
2285 {
2286         SPOOL_R_ENDDOCPRINTER r_u;
2287         int pnum = find_printer_index_by_hnd(&(q_u->handle));
2288
2289         if (OPEN_HANDLE(pnum))
2290         {
2291                 r_u.status=0x0;
2292
2293                 spoolss_io_r_enddocprinter("",&r_u,rdata,0);            
2294         }
2295         else
2296         {
2297                 DEBUG(3,("Error in enddocprinter printer handle (pnum=%x)\n",pnum));
2298         }
2299 }
2300
2301 /********************************************************************
2302  * api_spoolss_getprinter
2303  * called from the spoolss dispatcher
2304  *
2305  ********************************************************************/
2306 static void api_spoolss_enddocprinter(pipes_struct *p, prs_struct *data,
2307                                           prs_struct *rdata)
2308 {
2309         SPOOL_Q_ENDDOCPRINTER q_u;
2310         int pnum;
2311         int snum;
2312         pstring filename;
2313         pstring filename1;
2314         pstring job_name;
2315         pstring syscmd;
2316         char *tstr;
2317         
2318         spoolss_io_q_enddocprinter("", &q_u, data, 0);
2319         
2320         *syscmd=0;
2321         
2322         pnum = find_printer_index_by_hnd(&(q_u.handle));
2323         
2324         if (OPEN_HANDLE(pnum))
2325         {
2326                 Printer[pnum].document_started=False;
2327                 close(Printer[pnum].document_fd);
2328                 DEBUG(4,("Temp spool file closed, printing now ...\n"));
2329
2330                 pstrcpy(filename1, Printer[pnum].document_name);
2331                 pstrcpy(job_name, Printer[pnum].job_name);
2332                 
2333                 get_printer_snum(&(q_u.handle),&snum);
2334                 
2335                 /* copy the command into the buffer for extensive meddling. */
2336                 StrnCpy(syscmd, lp_printcommand(snum), sizeof(pstring) - 1);
2337
2338                 /* look for "%s" in the string. If there is no %s, we cannot print. */   
2339                 if (!strstr(syscmd, "%s") && !strstr(syscmd, "%f"))
2340                 {
2341                         DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum)));
2342                 }
2343
2344                 if (strstr(syscmd,"%s"))
2345                 {
2346                         pstrcpy(filename,filename1);
2347                         string_sub(syscmd, "%s", filename);
2348                 }
2349
2350                 string_sub(syscmd, "%f", filename1);
2351
2352                 /* Does the service have a printername? If not, make a fake and empty    */
2353                 /* printer name. That way a %p is treated sanely if no printer */
2354                 /* name was specified to replace it. This eventuality is logged.         */
2355                 tstr = lp_printername(snum);
2356                 if (tstr == NULL || tstr[0] == '\0')
2357                 {
2358                         DEBUG(3,( "No printer name - using %s.\n", SERVICE(snum)));
2359                         tstr = SERVICE(snum);
2360                 }
2361
2362                 string_sub(syscmd, "%p", tstr);
2363
2364                 /* If the lpr command support the 'Job' option replace here */
2365                 string_sub(syscmd, "%j", job_name);
2366
2367                 if ( *syscmd != '\0')
2368                 {
2369                   int ret = smbrun(syscmd, NULL, False);
2370                   DEBUG(3,("Running the command `%s' gave %d\n", syscmd, ret));
2371                 }
2372                 else
2373                   DEBUG(0,("Null print command?\n"));
2374
2375                 lpq_reset(snum);
2376         }
2377         
2378         spoolss_reply_enddocprinter(&q_u, rdata);
2379 }
2380
2381 /****************************************************************************
2382 ****************************************************************************/
2383 static void spoolss_reply_writeprinter(SPOOL_Q_WRITEPRINTER *q_u, prs_struct *rdata)
2384 {
2385         SPOOL_R_WRITEPRINTER r_u;
2386         int pnum = find_printer_index_by_hnd(&(q_u->handle));
2387
2388         if (OPEN_HANDLE(pnum))
2389         {
2390                 r_u.buffer_written=Printer[pnum].document_lastwritten;
2391                 r_u.status=0x0;
2392
2393                 spoolss_io_r_writeprinter("",&r_u,rdata,0);             
2394         }
2395         else
2396         {
2397                 DEBUG(3,("Error in writeprinter printer handle (pnum=%x)\n",pnum));
2398         }
2399 }
2400
2401 /********************************************************************
2402  * api_spoolss_getprinter
2403  * called from the spoolss dispatcher
2404  *
2405  ********************************************************************/
2406 static void api_spoolss_writeprinter(pipes_struct *p, prs_struct *data,
2407                                           prs_struct *rdata)
2408 {
2409         SPOOL_Q_WRITEPRINTER q_u;
2410         int pnum;
2411         int fd;
2412         int size;
2413         spoolss_io_q_writeprinter("", &q_u, data, 0);
2414         
2415         pnum = find_printer_index_by_hnd(&(q_u.handle));
2416         
2417         if (OPEN_HANDLE(pnum))
2418         {
2419                 fd=Printer[pnum].document_fd;
2420                 size=write(fd, q_u.buffer, q_u.buffer_size);
2421                 if (q_u.buffer) free(q_u.buffer);
2422                 Printer[pnum].document_lastwritten=size;
2423         }
2424         
2425         spoolss_reply_writeprinter(&q_u, rdata);
2426 }
2427
2428 /********************************************************************
2429  * api_spoolss_getprinter
2430  * called from the spoolss dispatcher
2431  *
2432  ********************************************************************/
2433 static void control_printer(PRINTER_HND handle, uint32 command, connection_struct *conn)
2434 {
2435         int pnum;
2436         int snum;
2437         pnum = find_printer_index_by_hnd(&(handle));
2438
2439         if ( get_printer_snum(&handle, &snum) )
2440         {                
2441                 switch (command)
2442                 {
2443                         case PRINTER_CONTROL_PAUSE:
2444                                 /* pause the printer here */
2445                                 status_printqueue(conn, snum, LPSTAT_STOPPED);
2446                                 break;
2447
2448                         case PRINTER_CONTROL_RESUME:
2449                         case PRINTER_CONTROL_UNPAUSE:
2450                                 /* UN-pause the printer here */
2451                                 status_printqueue(conn, snum, LPSTAT_OK);
2452                                 break;
2453                         case PRINTER_CONTROL_PURGE:
2454                                 /* Envoi des dragées FUCA dans l'imprimante */
2455                                 break;
2456                 }
2457         }
2458 }
2459
2460 /********************************************************************
2461  * called by spoolss_api_setprinter
2462  * when updating a printer description
2463  ********************************************************************/
2464 static void update_printer(PRINTER_HND handle, uint32 level,
2465                            SPOOL_PRINTER_INFO_LEVEL info, DEVICEMODE *devmode)
2466 {
2467         int pnum;
2468         int snum;
2469         NT_PRINTER_INFO_LEVEL printer;
2470         NT_DEVICEMODE *nt_devmode;
2471
2472         nt_devmode=NULL;
2473         
2474         DEBUG(8,("update_printer\n"));
2475         
2476         if (level!=2)
2477         {
2478                 DEBUG(0,("Send a mail to samba-bugs@samba.org\n"));
2479                 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
2480                 return;
2481         }
2482
2483         pnum = find_printer_index_by_hnd(&handle);
2484         
2485         if ( get_printer_snum(&handle, &snum) )
2486         {
2487                 get_a_printer(&printer, level, lp_servicename(snum));
2488
2489                 DEBUGADD(8,("Converting info_2 struct\n"));
2490                 convert_printer_info(info, &printer, level);
2491                 
2492                 if ((info.info_2)->devmode_ptr != 0)
2493                 {
2494                         /* we have a valid devmode
2495                            convert it and link it*/
2496                         
2497                         /* the nt_devmode memory is already alloced
2498                          * while doing the get_a_printer call
2499                          * but the devmode private part is not
2500                          * it's done by convert_devicemode
2501                          */
2502                         DEBUGADD(8,("Converting the devicemode struct\n"));
2503                         nt_devmode=printer.info_2->devmode;
2504                         
2505                         init_devicemode(nt_devmode);
2506                                         
2507                         convert_devicemode(*devmode, nt_devmode);
2508                         
2509                         /* now clear the memory used in 
2510                          * the RPC parsing routine
2511                          */
2512                         if (devmode->private != NULL)
2513                                 free(devmode->private);
2514                         free(devmode);
2515                 }
2516                 else
2517                 {
2518                         if (printer.info_2->devmode != NULL)
2519                         {
2520                                 free(printer.info_2->devmode);
2521                         }
2522                         printer.info_2->devmode=NULL;
2523                 }
2524                                 
2525                 add_a_printer(printer, level);
2526                 free_a_printer(printer, level);
2527         }       
2528 }
2529
2530 /****************************************************************************
2531 ****************************************************************************/
2532 static void spoolss_reply_setprinter(SPOOL_Q_SETPRINTER *q_u, prs_struct *rdata)
2533 {
2534         SPOOL_R_SETPRINTER r_u;
2535
2536         /*
2537           Let's the sun shine !!!
2538           Always respond everything is alright
2539         */
2540         
2541         r_u.status=0x0;
2542
2543         spoolss_io_r_setprinter("",&r_u,rdata,0);
2544 }
2545
2546 /****************************************************************************
2547 ****************************************************************************/
2548 static void api_spoolss_setprinter(pipes_struct *p, prs_struct *data,
2549                                    prs_struct *rdata)
2550 {
2551         SPOOL_Q_SETPRINTER q_u;
2552         int pnum;
2553         spoolss_io_q_setprinter("", &q_u, data, 0);
2554         
2555         pnum = find_printer_index_by_hnd(&(q_u.handle));
2556         
2557         if (OPEN_HANDLE(pnum))
2558         {
2559                 /* check the level */   
2560                 switch (q_u.level)
2561                 {
2562                         case 0:
2563                                 control_printer(q_u.handle, q_u.command, p->conn);
2564                                 break;
2565                         case 2:
2566                                 update_printer(q_u.handle, q_u.level, q_u.info, q_u.devmode);
2567                                 break;
2568                 }
2569         }
2570         spoolss_reply_setprinter(&q_u, rdata);
2571 }
2572
2573 /****************************************************************************
2574 ****************************************************************************/
2575 static void spoolss_reply_fcpn(SPOOL_Q_FCPN *q_u, prs_struct *rdata)
2576 {
2577         SPOOL_R_FCPN r_u;
2578         
2579         r_u.status=0x0;
2580
2581         spoolss_io_r_fcpn("",&r_u,rdata,0);             
2582 }
2583
2584 /****************************************************************************
2585 ****************************************************************************/
2586 static void api_spoolss_fcpn(pipes_struct *p, prs_struct *data,
2587                                    prs_struct *rdata)
2588 {
2589         SPOOL_Q_FCPN q_u;
2590         
2591         spoolss_io_q_fcpn("", &q_u, data, 0);
2592
2593         spoolss_reply_fcpn(&q_u, rdata);
2594 }
2595
2596 /****************************************************************************
2597 ****************************************************************************/
2598 static void spoolss_reply_addjob(SPOOL_Q_ADDJOB *q_u, prs_struct *rdata)
2599 {
2600         SPOOL_R_ADDJOB r_u;
2601         
2602         r_u.status=0x0;
2603
2604         spoolss_io_r_addjob("",&r_u,rdata,0);           
2605 }
2606
2607 /****************************************************************************
2608 ****************************************************************************/
2609 static void api_spoolss_addjob(pipes_struct *p, prs_struct *data,
2610                                    prs_struct *rdata)
2611 {
2612         SPOOL_Q_ADDJOB q_u;
2613         
2614         spoolss_io_q_addjob("", &q_u, data, 0);
2615
2616         spoolss_reply_addjob(&q_u, rdata);
2617         
2618         spoolss_io_free_buffer(&(q_u.buffer));
2619 }
2620
2621 /****************************************************************************
2622 ****************************************************************************/
2623 static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
2624                             int position, int snum)
2625 {
2626         pstring temp_name;
2627         
2628         struct tm *t;
2629         time_t unixdate = time(NULL);
2630         
2631         t=gmtime(&unixdate);
2632         snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
2633
2634         job_info->jobid=queue->job;     
2635         make_unistr(&(job_info->printername), lp_servicename(snum));
2636         make_unistr(&(job_info->machinename), temp_name);
2637         make_unistr(&(job_info->username), queue->user);
2638         make_unistr(&(job_info->document), queue->file);
2639         make_unistr(&(job_info->datatype), "RAW");
2640         make_unistr(&(job_info->text_status), "");
2641         job_info->status=queue->status;
2642         job_info->priority=queue->priority;
2643         job_info->position=position;
2644         job_info->totalpages=0;
2645         job_info->pagesprinted=0;
2646
2647         make_systemtime(&(job_info->submitted), t);
2648 }
2649
2650 /****************************************************************************
2651 ****************************************************************************/
2652 static void fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
2653                             int position, int snum)
2654 {
2655         pstring temp_name;
2656
2657         struct tm *t;
2658         time_t unixdate = time(NULL);
2659         
2660         t=gmtime(&unixdate);
2661         snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
2662
2663         job_info->jobid=queue->job;
2664         make_unistr(&(job_info->printername), lp_servicename(snum));
2665         make_unistr(&(job_info->machinename), temp_name);
2666         make_unistr(&(job_info->username), queue->user);
2667         make_unistr(&(job_info->document), queue->file);
2668         make_unistr(&(job_info->notifyname), queue->user);
2669         make_unistr(&(job_info->datatype), "RAW");
2670         make_unistr(&(job_info->printprocessor), "winprint");
2671         make_unistr(&(job_info->parameters), "");
2672
2673 /* here the devicemode should be filled up */
2674
2675         make_unistr(&(job_info->text_status), "");
2676         
2677 /* and here the security descriptor */
2678
2679         job_info->status=queue->status;
2680         job_info->priority=queue->priority;
2681         job_info->position=position;
2682         job_info->starttime=0;
2683         job_info->untiltime=0;
2684         job_info->totalpages=0;
2685         job_info->size=queue->size;
2686         make_systemtime(&(job_info->submitted), t);
2687         job_info->timeelapsed=0;
2688         job_info->pagesprinted=0;
2689 }
2690
2691 /****************************************************************************
2692 ****************************************************************************/
2693 static void spoolss_reply_enumjobs(SPOOL_Q_ENUMJOBS *q_u, prs_struct *rdata, connection_struct *conn)
2694 {
2695         SPOOL_R_ENUMJOBS r_u;
2696         int snum;
2697         int count;
2698         int i;
2699         print_queue_struct *queue=NULL;
2700         print_status_struct status;
2701         JOB_INFO_1 *job_info_1=NULL;
2702         JOB_INFO_2 *job_info_2=NULL;
2703
2704         DEBUG(4,("spoolss_reply_enumjobs\n"));
2705         
2706         bzero(&status,sizeof(status));
2707
2708         r_u.offered=q_u->buf_size;
2709
2710
2711         if (get_printer_snum(&(q_u->handle), &snum))
2712         {
2713                 count=get_printqueue(snum, conn, &queue, &status);
2714                 r_u.numofjobs=count;
2715                 
2716                 r_u.level=q_u->level;
2717                 
2718                 DEBUG(4,("count:[%d], status:[%d], [%s]\n", count, status.status, status.message));
2719                 
2720                 switch (r_u.level)
2721                 {
2722                         case 1:
2723                         {
2724                                 job_info_1=(JOB_INFO_1 *)malloc(count*sizeof(JOB_INFO_1));
2725
2726                                 for (i=0; i<count; i++)
2727                                 {
2728                                         fill_job_info_1(&(job_info_1[i]), &(queue[i]), i, snum);
2729                                 }
2730                                 r_u.job.job_info_1=job_info_1;
2731                                 break;
2732                         }
2733                         case 2:
2734                         {
2735                                 job_info_2=(JOB_INFO_2 *)malloc(count*sizeof(JOB_INFO_2));
2736
2737                                 for (i=0; i<count; i++)
2738                                 {
2739                                         fill_job_info_2(&(job_info_2[i]), &(queue[i]), i, snum);
2740                                 }
2741                                 r_u.job.job_info_2=job_info_2;
2742                                 break;
2743                         }
2744                 }
2745         }
2746
2747         r_u.status=0x0;
2748
2749         spoolss_io_r_enumjobs("",&r_u,rdata,0);
2750         switch (r_u.level)
2751         {
2752                 case 1:
2753                 {
2754                         free(job_info_1);
2755                         break;
2756                 }
2757                 case 2:
2758                 {
2759                         free(job_info_2);
2760                         break;
2761                 }
2762         }
2763         if (queue) free(queue);
2764
2765 }
2766
2767 /****************************************************************************
2768 ****************************************************************************/
2769 static void api_spoolss_enumjobs(pipes_struct *p, prs_struct *data,
2770                                    prs_struct *rdata)
2771 {
2772         SPOOL_Q_ENUMJOBS q_u;
2773         
2774         spoolss_io_q_enumjobs("", &q_u, data, 0);
2775
2776         spoolss_reply_enumjobs(&q_u, rdata, p->conn);
2777         
2778         spoolss_io_free_buffer(&(q_u.buffer));
2779 }
2780
2781 /****************************************************************************
2782 ****************************************************************************/
2783 static void spoolss_reply_schedulejob(SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *rdata)
2784 {
2785         SPOOL_R_SCHEDULEJOB r_u;
2786         
2787         r_u.status=0x0;
2788
2789         spoolss_io_r_schedulejob("",&r_u,rdata,0);              
2790 }
2791
2792 /****************************************************************************
2793 ****************************************************************************/
2794 static void api_spoolss_schedulejob(pipes_struct *p, prs_struct *data,
2795                                    prs_struct *rdata)
2796 {
2797         SPOOL_Q_SCHEDULEJOB q_u;
2798         
2799         spoolss_io_q_schedulejob("", &q_u, data, 0);
2800
2801         spoolss_reply_schedulejob(&q_u, rdata);
2802 }
2803
2804 /****************************************************************************
2805 ****************************************************************************/
2806 static void spoolss_reply_setjob(SPOOL_Q_SETJOB *q_u, prs_struct *rdata, connection_struct *conn)
2807 {
2808         SPOOL_R_SETJOB r_u;
2809         int snum;
2810         print_queue_struct *queue=NULL;
2811         print_status_struct status;
2812         int i=0;
2813         BOOL found=False;
2814         int count;
2815                 
2816         bzero(&status,sizeof(status));
2817
2818         if (get_printer_snum(&(q_u->handle), &snum))
2819         {
2820                 count=get_printqueue(snum, conn, &queue, &status);              
2821                 while ( (i<count) && found==False )
2822                 {
2823                         if ( q_u->jobid == queue[i].job )
2824                         {
2825                                 found=True;
2826                         }
2827                         i++;
2828                 }
2829                 
2830                 if (found==True)
2831                 {
2832                         switch (q_u->command)
2833                         {
2834                                 case JOB_CONTROL_CANCEL:
2835                                 case JOB_CONTROL_DELETE:
2836                                 {
2837                                         del_printqueue(conn, snum, q_u->jobid);
2838                                         break;
2839                                 }
2840                                 case JOB_CONTROL_PAUSE:
2841                                 {
2842                                         status_printjob(conn, snum, q_u->jobid, LPQ_PAUSED);
2843                                         break;
2844                                 }
2845                                 case JOB_CONTROL_RESUME:
2846                                 {
2847                                         status_printjob(conn, snum, q_u->jobid, LPQ_QUEUED);
2848                                         break;
2849                                 }
2850                         }
2851                 }
2852         }
2853         r_u.status=0x0;
2854         spoolss_io_r_setjob("",&r_u,rdata,0);
2855         if (queue) free(queue);
2856
2857 }
2858
2859 /****************************************************************************
2860 ****************************************************************************/
2861 static void api_spoolss_setjob(pipes_struct *p, prs_struct *data,
2862                                    prs_struct *rdata)
2863 {
2864         SPOOL_Q_SETJOB q_u;
2865         
2866         spoolss_io_q_setjob("", &q_u, data, 0);
2867
2868         spoolss_reply_setjob(&q_u, rdata, p->conn);
2869 }
2870
2871 /****************************************************************************
2872 ****************************************************************************/
2873 static void spoolss_reply_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *rdata, connection_struct *conn)
2874 {
2875         SPOOL_R_ENUMPRINTERDRIVERS r_u;
2876         NT_PRINTER_DRIVER_INFO_LEVEL driver;
2877         int count;
2878         int i;
2879         fstring *list;
2880         DRIVER_INFO_1 *driver_info_1=NULL;
2881         DRIVER_INFO_2 *driver_info_2=NULL;
2882         DRIVER_INFO_3 *driver_info_3=NULL;
2883         fstring servername;
2884         fstring architecture;
2885
2886         DEBUG(4,("spoolss_reply_enumdrivers\n"));
2887         fstrcpy(servername, global_myname);
2888
2889         unistr2_to_ascii(architecture, &(q_u->environment), sizeof(architecture));
2890         count=get_ntdrivers(conn, &list, architecture);
2891
2892         DEBUGADD(4,("we have: [%d] drivers on archi [%s]\n",count, architecture));
2893         for (i=0; i<count; i++)
2894         {
2895                 DEBUGADD(5,("driver [%s]\n",list[i]));
2896         }
2897         
2898         r_u.offered=q_u->buf_size;
2899         r_u.numofdrivers=count;
2900         r_u.level=q_u->level;
2901         
2902         switch (r_u.level)
2903         {
2904                 case 1:
2905                 {
2906                         driver_info_1=(DRIVER_INFO_1 *)malloc(count*sizeof(DRIVER_INFO_1));
2907
2908                         for (i=0; i<count; i++)
2909                         {
2910                                 get_a_printer_driver(&driver, 3, list[i], architecture);
2911                                 fill_printer_driver_info_1(&(driver_info_1[i]), driver, servername, architecture );
2912                                 free_a_printer_driver(driver, 3);
2913                         }
2914                         r_u.driver.driver_info_1=driver_info_1;
2915                         break;
2916                 }
2917                 case 2:
2918                 {
2919                         driver_info_2=(DRIVER_INFO_2 *)malloc(count*sizeof(DRIVER_INFO_2));
2920
2921                         for (i=0; i<count; i++)
2922                         {
2923                                 get_a_printer_driver(&driver, 3, list[i], architecture);
2924                                 fill_printer_driver_info_2(&(driver_info_2[i]), driver, servername, architecture );
2925                                 free_a_printer_driver(driver, 3);
2926                         }
2927                         r_u.driver.driver_info_2=driver_info_2;
2928                         break;
2929                 }
2930                 case 3:
2931                 {
2932                         driver_info_3=(DRIVER_INFO_3 *)malloc(count*sizeof(DRIVER_INFO_3));
2933
2934                         for (i=0; i<count; i++)
2935                         {
2936                                 get_a_printer_driver(&driver, 3, list[i], architecture);
2937                                 fill_printer_driver_info_3(&(driver_info_3[i]), driver, servername, architecture );
2938                                 free_a_printer_driver(driver, 3);
2939                         }
2940                         r_u.driver.driver_info_3=driver_info_3;
2941                         break;
2942                 }
2943         }
2944
2945         r_u.status=0x0;
2946
2947         spoolss_io_r_enumdrivers("",&r_u,rdata,0);
2948
2949         switch (r_u.level)
2950         {
2951                 case 1:
2952                 {
2953                         free(driver_info_1);
2954                         break;
2955                 }
2956                 case 2:
2957                 {
2958                         free(driver_info_2);
2959                         break;
2960                 }
2961                 case 3:
2962                 {
2963                         free(driver_info_3);
2964                         break;
2965                 }
2966         }
2967 }
2968
2969 /****************************************************************************
2970 ****************************************************************************/
2971
2972 static void api_spoolss_enumprinterdrivers(pipes_struct *p, prs_struct *data,
2973                                    prs_struct *rdata)
2974 {
2975         SPOOL_Q_ENUMPRINTERDRIVERS q_u;
2976         
2977         spoolss_io_q_enumprinterdrivers("", &q_u, data, 0);
2978
2979         spoolss_reply_enumprinterdrivers(&q_u, rdata, p->conn);
2980         
2981         spoolss_io_free_buffer(&(q_u.buffer));
2982 }
2983
2984
2985 /****************************************************************************
2986 ****************************************************************************/
2987 static void fill_form_1(FORM_1 *form, nt_forms_struct *list, int position)
2988 {
2989         form->flag=list->flag;
2990         make_unistr(&(form->name), list->name);
2991         form->width=list->width;
2992         form->length=list->length;
2993         form->left=list->left;
2994         form->top=list->top;
2995         form->right=list->right;
2996         form->bottom=list->bottom;      
2997 }
2998
2999 /****************************************************************************
3000 ****************************************************************************/
3001 static void spoolss_reply_enumforms(SPOOL_Q_ENUMFORMS *q_u, prs_struct *rdata)
3002 {
3003         SPOOL_R_ENUMFORMS r_u;
3004         int count;
3005         int i;
3006         nt_forms_struct *list=NULL;
3007         FORM_1 *forms_1=NULL;
3008
3009         DEBUG(4,("spoolss_reply_enumforms\n"));
3010         
3011         count=get_ntforms(&list);
3012         r_u.offered=q_u->buf_size;
3013         r_u.numofforms=count;
3014         r_u.level=q_u->level;
3015         r_u.status=0x0;
3016
3017         DEBUGADD(5,("Offered buffer size [%d]\n", r_u.offered));
3018         DEBUGADD(5,("Number of forms [%d]\n",     r_u.numofforms));
3019         DEBUGADD(5,("Info level [%d]\n",          r_u.level));
3020                 
3021         switch (r_u.level)
3022         {
3023                 case 1:
3024                 {
3025                         forms_1=(FORM_1 *)malloc(count*sizeof(FORM_1));
3026                         for (i=0; i<count; i++)
3027                         {
3028                                 DEBUGADD(6,("Filling form number [%d]\n",i));
3029                                 fill_form_1(&(forms_1[i]), &(list[i]), i);
3030                         }
3031                         r_u.forms_1=forms_1;
3032                         break;
3033                 }
3034         }
3035         spoolss_io_r_enumforms("",&r_u,rdata,0);
3036         switch (r_u.level)
3037         {
3038                 case 1:
3039                 {
3040                         free(forms_1);
3041                         break;
3042                 }
3043         }
3044         free(list);
3045 }
3046
3047 /****************************************************************************
3048 ****************************************************************************/
3049 static void api_spoolss_enumforms(pipes_struct *p, prs_struct *data,
3050                                    prs_struct *rdata)
3051 {
3052         SPOOL_Q_ENUMFORMS q_u;
3053         
3054         spoolss_io_q_enumforms("", &q_u, data, 0);
3055
3056         spoolss_reply_enumforms(&q_u, rdata);
3057         
3058         spoolss_io_free_buffer(&(q_u.buffer));
3059 }
3060
3061 /****************************************************************************
3062 ****************************************************************************/
3063 static void fill_port_2(PORT_INFO_2 *port, char *name)
3064 {
3065         make_unistr(&(port->port_name), name);
3066         make_unistr(&(port->monitor_name), "Moniteur Local");
3067         make_unistr(&(port->description), "Local Port");
3068 #define PORT_TYPE_WRITE 1
3069         port->port_type=PORT_TYPE_WRITE;
3070         port->reserved=0x0;     
3071 }
3072
3073 /****************************************************************************
3074 ****************************************************************************/
3075 static void spoolss_reply_enumports(SPOOL_Q_ENUMPORTS *q_u, prs_struct *rdata)
3076 {
3077         SPOOL_R_ENUMPORTS r_u;
3078         int i=0;
3079         PORT_INFO_2 *ports_2=NULL;
3080         int n_services=lp_numservices();
3081         int snum;
3082
3083         DEBUG(4,("spoolss_reply_enumports\n"));
3084         
3085         r_u.offered=q_u->buf_size;
3086         r_u.level=q_u->level;
3087         r_u.status=0x0;
3088                 
3089         switch (r_u.level)
3090         {
3091                 case 2:
3092                 {
3093                         ports_2=(PORT_INFO_2 *)malloc(n_services*sizeof(PORT_INFO_2));
3094                         for (snum=0; snum<n_services; snum++)
3095                         {
3096                                 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3097                                 {
3098                                         DEBUGADD(6,("Filling port number [%d]\n",i));
3099                                         fill_port_2(&(ports_2[i]), lp_servicename(snum));
3100                                         i++;
3101                                 }
3102                         }
3103                         r_u.port.port_info_2=ports_2;
3104                         break;
3105                 }
3106         }
3107         r_u.numofports=i;
3108         spoolss_io_r_enumports("",&r_u,rdata,0);
3109         switch (r_u.level)
3110         {
3111                 case 2:
3112                 {
3113                         free(ports_2);
3114                         break;
3115                 }
3116         }
3117 }
3118
3119 /****************************************************************************
3120 ****************************************************************************/
3121 static void api_spoolss_enumports(pipes_struct *p, prs_struct *data,
3122                                    prs_struct *rdata)
3123 {
3124         SPOOL_Q_ENUMPORTS q_u;
3125         
3126         spoolss_io_q_enumports("", &q_u, data, 0);
3127
3128         spoolss_reply_enumports(&q_u, rdata);
3129         
3130         spoolss_io_free_buffer(&(q_u.buffer));
3131 }
3132
3133 /****************************************************************************
3134 ****************************************************************************/
3135 static void spoolss_reply_addprinterex(SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *rdata)
3136 {
3137         SPOOL_R_ADDPRINTEREX r_u;
3138         BOOL printer_open = False;
3139         fstring ascii_name;
3140         fstring server_name;
3141         fstring share_name;
3142         UNISTR2 *portname;
3143         SPOOL_PRINTER_INFO_LEVEL_2 *info2;
3144         SPOOL_PRINTER_INFO_LEVEL *info;
3145         
3146         info=&(q_u->info);
3147         info2=info->info_2;
3148         portname=&(info2->portname);
3149
3150         r_u.status=0x0; /* everything is always nice in this world */
3151
3152         StrnCpy(server_name, global_myname, strlen(global_myname) );
3153         unistr2_to_ascii(share_name, portname, sizeof(share_name)-1);
3154         
3155         slprintf(ascii_name, sizeof(ascii_name)-1, "\\\\%s\\%s", 
3156                  server_name, share_name);
3157                 
3158         printer_open = open_printer_hnd(&(r_u.handle));
3159         set_printer_hnd_printertype(&(r_u.handle), ascii_name);
3160         set_printer_hnd_printername(&(r_u.handle), ascii_name);
3161
3162         spoolss_io_r_addprinterex("", &r_u, rdata, 0);
3163 }
3164
3165 /****************************************************************************
3166 ****************************************************************************/
3167 static void api_spoolss_addprinterex(pipes_struct *p, prs_struct *data, prs_struct *rdata)
3168 {
3169         SPOOL_Q_ADDPRINTEREX q_u;
3170         NT_PRINTER_INFO_LEVEL printer;  
3171         
3172         /* read the stream and decode */
3173         spoolss_io_q_addprinterex("", &q_u, data, 0);
3174
3175         /* NULLify info_2 here */
3176         /* don't put it in convert_printer_info as it's used also with non-NULL values */
3177         printer.info_2=NULL;
3178
3179         /* convert from UNICODE to ASCII */
3180         convert_printer_info(q_u.info, &printer, q_u.level);
3181
3182         /* write the ASCII on disk */
3183         add_a_printer(printer, q_u.level);
3184
3185         spoolss_reply_addprinterex(&q_u, rdata);
3186         /* free mem used in q_u and r_u */
3187         
3188         /* free_add_printer(q_u, r_u); */
3189 }
3190
3191 /****************************************************************************
3192 ****************************************************************************/
3193 static void spoolss_reply_addprinterdriver(SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *rdata)
3194 {
3195         SPOOL_R_ADDPRINTERDRIVER r_u;
3196
3197         r_u.status=0x0; /* everything is always nice in this world */
3198
3199         spoolss_io_r_addprinterdriver("", &r_u, rdata, 0);
3200 }
3201
3202 /****************************************************************************
3203 ****************************************************************************/
3204 static void api_spoolss_addprinterdriver(pipes_struct *p, prs_struct *data,
3205                                          prs_struct *rdata)
3206 {
3207         SPOOL_Q_ADDPRINTERDRIVER q_u;
3208         NT_PRINTER_DRIVER_INFO_LEVEL driver;
3209         
3210         spoolss_io_q_addprinterdriver("", &q_u, data, 0);
3211
3212         convert_printer_driver_info(q_u.info, &driver, q_u.level);
3213
3214         add_a_printer_driver(driver, q_u.level);
3215
3216         spoolss_reply_addprinterdriver(&q_u, rdata);
3217         /* free mem used in q_u and r_u */
3218 }
3219
3220 /****************************************************************************
3221 ****************************************************************************/
3222 static void spoolss_reply_getprinterdriverdirectory(SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *rdata)
3223 {
3224         SPOOL_R_GETPRINTERDRIVERDIR r_u;
3225         pstring chaine;
3226         pstring long_archi;
3227         pstring archi;
3228
3229         r_u.offered=q_u->buf_size;
3230         r_u.level=q_u->level;
3231         r_u.status=0x0;
3232         
3233         unistr2_to_ascii(long_archi, &(q_u->environment), sizeof(long_archi)-1);
3234         get_short_archi(archi, long_archi);
3235                 
3236         slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\print$\\%s", global_myname, archi);
3237
3238         DEBUG(4,("printer driver directory: [%s]\n", chaine));
3239                                                             
3240         make_unistr(&(r_u.driver.driver_info_1.name), chaine);
3241
3242         spoolss_io_r_getprinterdriverdir("", &r_u, rdata, 0);
3243 }
3244
3245 /****************************************************************************
3246 ****************************************************************************/
3247 static void api_spoolss_getprinterdriverdirectory(pipes_struct *p, prs_struct *data,
3248                                                   prs_struct *rdata)
3249 {
3250         SPOOL_Q_GETPRINTERDRIVERDIR q_u;
3251         
3252         spoolss_io_q_getprinterdriverdir("", &q_u, data, 0);
3253         
3254         spoolss_reply_getprinterdriverdirectory(&q_u, rdata);
3255         
3256         spoolss_io_free_buffer(&(q_u.buffer));
3257 }
3258
3259 /****************************************************************************
3260 ****************************************************************************/
3261 static void spoolss_reply_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *rdata)
3262 {
3263         SPOOL_R_ENUMPRINTERDATA r_u;
3264         NT_PRINTER_INFO_LEVEL printer;
3265         
3266         uint32 type;
3267         fstring value;
3268         uint8 *data;
3269         
3270         uint32 param_index;
3271         uint32 biggest_valuesize;
3272         uint32 biggest_datasize;
3273         uint32 data_len;
3274         
3275         int pnum = find_printer_index_by_hnd(&(q_u->handle));
3276         int snum;
3277         
3278         DEBUG(5,("spoolss_reply_enumprinterdata\n"));
3279
3280         if (OPEN_HANDLE(pnum))
3281         {
3282                 get_printer_snum(&(q_u->handle), &snum);
3283                 get_a_printer(&printer, 2, lp_servicename(snum));
3284
3285                 /* The NT machine wants to know the biggest size of value and data */   
3286                 if ( (q_u->valuesize==0) && (q_u->datasize==0) )
3287                 {
3288                         DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
3289                         
3290                         r_u.valuesize=0;
3291                         r_u.realvaluesize=0;
3292                         r_u.type=0;
3293                         r_u.datasize=0;
3294                         r_u.realdatasize=0;
3295                         
3296                         param_index=0;
3297                         biggest_valuesize=0;
3298                         biggest_datasize=0;
3299                         
3300                         while (get_specific_param_by_index(printer, 2, param_index, value, &data, &type, &data_len))
3301                         {
3302                                 if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
3303                                 if (data_len  > biggest_datasize)  biggest_datasize=data_len;
3304
3305                                 param_index++;
3306                         }
3307                         
3308                         /* I wrote it, I didn't designed the protocol */
3309                         SIVAL(&(r_u.value),0, 2*(biggest_valuesize+1) );
3310                         r_u.data=(uint8 *)malloc(4*sizeof(uint8));
3311                         SIVAL(r_u.data, 0, biggest_datasize );
3312                 }
3313                 else
3314                 {
3315                         /* 
3316                          * the value len is wrong in NT sp3
3317                          * that's the number of bytes not the number of unicode chars
3318                          */
3319                          
3320                         r_u.valuesize=q_u->valuesize;
3321                         r_u.datasize=q_u->datasize;
3322
3323                         if (get_specific_param_by_index(printer, 2, q_u->index, value, &data, &type, &data_len))
3324                         {
3325                                 make_unistr(&(r_u.value), value);
3326                                 r_u.data=data;
3327                                 
3328                                 r_u.type=type;
3329
3330                                 /* the length are in bytes including leading NULL */
3331                                 r_u.realvaluesize=2*(strlen(value)+1);
3332                                 r_u.realdatasize=data_len;
3333                                 
3334                                 r_u.status=0;
3335                         }
3336                         else
3337                         {
3338                                 r_u.valuesize=0;
3339                                 r_u.realvaluesize=0;
3340                                 r_u.datasize=0;
3341                                 r_u.realdatasize=0;
3342                                 r_u.type=0;
3343                                 r_u.status=0x0103; /* ERROR_NO_MORE_ITEMS */
3344                         }               
3345                 }
3346                 
3347                 free_a_printer(printer, 2);
3348         }
3349         spoolss_io_r_enumprinterdata("", &r_u, rdata, 0);
3350         free(r_u.data);
3351 }
3352
3353 /****************************************************************************
3354 ****************************************************************************/
3355 static void api_spoolss_enumprinterdata(pipes_struct *p, prs_struct *data,
3356                                                   prs_struct *rdata)
3357 {
3358         SPOOL_Q_ENUMPRINTERDATA q_u;
3359         
3360         spoolss_io_q_enumprinterdata("", &q_u, data, 0);
3361         
3362         spoolss_reply_enumprinterdata(&q_u, rdata);
3363 }
3364
3365 /****************************************************************************
3366 ****************************************************************************/
3367 static void spoolss_reply_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *rdata)
3368 {
3369         SPOOL_R_SETPRINTERDATA r_u;     
3370         NT_PRINTER_INFO_LEVEL printer;
3371         NT_PRINTER_PARAM *param = NULL;
3372                 
3373         int pnum=0;
3374         int snum=0;
3375         
3376         DEBUG(5,("spoolss_reply_setprinterdata\n"));
3377
3378         pnum = find_printer_index_by_hnd(&(q_u->handle));
3379         
3380         if (OPEN_HANDLE(pnum))
3381         {
3382                 get_printer_snum(&(q_u->handle), &snum);                
3383                 get_a_printer(&printer, 2, lp_servicename(snum));
3384                 convert_specific_param(&param, q_u->value , q_u->type, q_u->data, q_u->real_len);
3385
3386                 unlink_specific_param_if_exist(printer.info_2, param);
3387                 
3388                 add_a_specific_param(printer.info_2, param);
3389                 
3390                 add_a_printer(printer, 2);
3391                 
3392                 free_a_printer(printer, 2);
3393         }       
3394         
3395         r_u.status = 0x0;
3396         spoolss_io_r_setprinterdata("", &r_u, rdata, 0);
3397 }
3398
3399 /****************************************************************************
3400 ****************************************************************************/
3401 static void api_spoolss_setprinterdata(pipes_struct *p, prs_struct *data,
3402                                        prs_struct *rdata)
3403 {
3404         SPOOL_Q_SETPRINTERDATA q_u;
3405         
3406         spoolss_io_q_setprinterdata("", &q_u, data, 0);
3407         
3408         spoolss_reply_setprinterdata(&q_u, rdata);
3409         
3410         free(q_u.data);
3411 }
3412
3413 /****************************************************************************
3414 ****************************************************************************/
3415 static void spoolss_reply_addform(SPOOL_Q_ADDFORM *q_u, prs_struct *rdata)
3416 {
3417        SPOOL_R_ADDFORM r_u;
3418        int pnum=0;
3419        int count=0;
3420        nt_forms_struct *list=NULL;
3421
3422        DEBUG(5,("spoolss_reply_addform\n"));
3423
3424        pnum = find_printer_index_by_hnd(&(q_u->handle));
3425
3426        if (OPEN_HANDLE(pnum))
3427        {
3428                count=get_ntforms(&list);
3429
3430                add_a_form(&list, q_u->form, count);
3431
3432                write_ntforms(&list, count+1);
3433
3434                free(list);
3435        }
3436
3437        r_u.status = 0x0;
3438        spoolss_io_r_addform("", &r_u, rdata, 0);
3439 }
3440
3441 /****************************************************************************
3442 ****************************************************************************/
3443 static void api_spoolss_addform(pipes_struct *p, prs_struct *data,
3444                                 prs_struct *rdata)
3445 {
3446        SPOOL_Q_ADDFORM q_u;
3447
3448        spoolss_io_q_addform("", &q_u, data, 0);
3449
3450        spoolss_reply_addform(&q_u, rdata);
3451 }
3452
3453
3454 /****************************************************************************
3455 ****************************************************************************/
3456 static void spoolss_reply_setform(SPOOL_Q_SETFORM *q_u, prs_struct *rdata)
3457 {
3458         SPOOL_R_SETFORM r_u;
3459         int pnum=0;
3460         int count=0;
3461         nt_forms_struct *list=NULL;
3462
3463         DEBUG(5,("spoolss_reply_setform\n"));
3464
3465         pnum = find_printer_index_by_hnd(&(q_u->handle));
3466
3467         if (OPEN_HANDLE(pnum))
3468         {
3469                 count=get_ntforms(&list);
3470
3471                 update_a_form(&list, q_u->form, count);
3472
3473                 write_ntforms(&list, count);
3474
3475                 free(list);
3476         }
3477         r_u.status = 0x0;
3478         spoolss_io_r_setform("", &r_u, rdata, 0);
3479 }
3480
3481 /****************************************************************************
3482 ****************************************************************************/
3483 static void api_spoolss_setform(pipes_struct *p, prs_struct *data,
3484                                 prs_struct *rdata)
3485 {
3486         SPOOL_Q_SETFORM q_u;
3487
3488         spoolss_io_q_setform("", &q_u, data, 0);
3489
3490         spoolss_reply_setform(&q_u, rdata);
3491 }
3492
3493 /*******************************************************************
3494 \pipe\spoolss commands
3495 ********************************************************************/
3496 struct api_struct api_spoolss_cmds[] =
3497 {
3498  {"SPOOLSS_OPENPRINTEREX",             SPOOLSS_OPENPRINTEREX,             api_spoolss_open_printer              },
3499  {"SPOOLSS_GETPRINTERDATA",            SPOOLSS_GETPRINTERDATA,            api_spoolss_getprinterdata            },
3500  {"SPOOLSS_CLOSEPRINTER",              SPOOLSS_CLOSEPRINTER,              api_spoolss_closeprinter              },
3501  {"SPOOLSS_RFFPCNEX",                  SPOOLSS_RFFPCNEX,                  api_spoolss_rffpcnex                  },
3502  {"SPOOLSS_RFNPCNEX",                  SPOOLSS_RFNPCNEX,                  api_spoolss_rfnpcnex                  },
3503  {"SPOOLSS_ENUMPRINTERS",              SPOOLSS_ENUMPRINTERS,              api_spoolss_enumprinters              },
3504  {"SPOOLSS_GETPRINTER",                SPOOLSS_GETPRINTER,                api_spoolss_getprinter                },
3505  {"SPOOLSS_GETPRINTERDRIVER2",         SPOOLSS_GETPRINTERDRIVER2,         api_spoolss_getprinterdriver2         }, 
3506  {"SPOOLSS_STARTPAGEPRINTER",          SPOOLSS_STARTPAGEPRINTER,          api_spoolss_startpageprinter          },
3507  {"SPOOLSS_ENDPAGEPRINTER",            SPOOLSS_ENDPAGEPRINTER,            api_spoolss_endpageprinter            }, 
3508  {"SPOOLSS_STARTDOCPRINTER",           SPOOLSS_STARTDOCPRINTER,           api_spoolss_startdocprinter           },
3509  {"SPOOLSS_ENDDOCPRINTER",             SPOOLSS_ENDDOCPRINTER,             api_spoolss_enddocprinter             },
3510  {"SPOOLSS_WRITEPRINTER",              SPOOLSS_WRITEPRINTER,              api_spoolss_writeprinter              },
3511  {"SPOOLSS_SETPRINTER",                SPOOLSS_SETPRINTER,                api_spoolss_setprinter                },
3512  {"SPOOLSS_FCPN",                      SPOOLSS_FCPN,                      api_spoolss_fcpn                      },
3513  {"SPOOLSS_ADDJOB",                    SPOOLSS_ADDJOB,                    api_spoolss_addjob                    },
3514  {"SPOOLSS_ENUMJOBS",                  SPOOLSS_ENUMJOBS,                  api_spoolss_enumjobs                  },
3515  {"SPOOLSS_SCHEDULEJOB",               SPOOLSS_SCHEDULEJOB,               api_spoolss_schedulejob               },
3516  {"SPOOLSS_SETJOB",                    SPOOLSS_SETJOB,                    api_spoolss_setjob                    },
3517  {"SPOOLSS_ENUMFORMS",                 SPOOLSS_ENUMFORMS,                 api_spoolss_enumforms                 },
3518  {"SPOOLSS_ENUMPORTS",                 SPOOLSS_ENUMPORTS,                 api_spoolss_enumports                 },
3519  {"SPOOLSS_ENUMPRINTERDRIVERS",        SPOOLSS_ENUMPRINTERDRIVERS,        api_spoolss_enumprinterdrivers        },
3520  {"SPOOLSS_ADDPRINTEREX",              SPOOLSS_ADDPRINTEREX,              api_spoolss_addprinterex              },
3521  {"SPOOLSS_ADDPRINTERDRIVER",          SPOOLSS_ADDPRINTERDRIVER,          api_spoolss_addprinterdriver          },
3522  {"SPOOLSS_GETPRINTERDRIVERDIRECTORY", SPOOLSS_GETPRINTERDRIVERDIRECTORY, api_spoolss_getprinterdriverdirectory },
3523  {"SPOOLSS_ENUMPRINTERDATA",           SPOOLSS_ENUMPRINTERDATA,           api_spoolss_enumprinterdata           },
3524  {"SPOOLSS_SETPRINTERDATA",            SPOOLSS_SETPRINTERDATA,            api_spoolss_setprinterdata            },
3525  {"SPOOLSS_ADDFORM",                   SPOOLSS_ADDFORM,                   api_spoolss_addform                   },
3526  {"SPOOLSS_SETFORM",                   SPOOLSS_SETFORM,                   api_spoolss_setform                   },
3527  { NULL,                               0,                                 NULL                                  }
3528 };
3529
3530 /*******************************************************************
3531 receives a spoolss pipe and responds.
3532 ********************************************************************/
3533 BOOL api_spoolss_rpc(pipes_struct *p, prs_struct *data)
3534 {
3535         return api_rpcTNP(p, "api_spoolss_rpc", api_spoolss_cmds, data);
3536 }
3537