2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 extern int DEBUGLEVEL;
27 /****************************************************************************
29 ****************************************************************************/
30 static BOOL parse_form_entry(char *line, nt_forms_struct *buf)
44 tok[0] = strtok(line,":");
46 if (!tok[0]) return False;
48 /* strip the comment lines */
49 if (tok[0][0]=='#') return (False);
52 while ( ((tok[count] = strtok(NULL,":")) != NULL ) && count<MAXTOK-1)
57 if (count < MAXTOK-1) return False;
59 StrnCpy(buf->name,tok[NAMETOK],sizeof(buf->name)-1);
60 buf->flag=atoi(tok[FLAGTOK]);
61 buf->width=atoi(tok[WIDTHTOK]);
62 buf->length=atoi(tok[LENGTHTOK]);
63 buf->left=atoi(tok[LEFTTOK]);
64 buf->top=atoi(tok[TOPTOK]);
65 buf->right=atoi(tok[RIGHTTOK]);
66 buf->bottom=atoi(tok[BOTTOMTOK]);
71 /****************************************************************************
72 get a form struct list
73 ****************************************************************************/
74 int get_ntforms(nt_forms_struct **list)
77 char *lp_forms = lp_nt_forms();
82 lines = file_lines_load(lp_forms, NULL);
89 for (i=0; lines[i]; i++) {
90 char *line = lines[i];
92 *list = Realloc(*list, sizeof(nt_forms_struct)*(total+1));
98 memset( (char *)&(*list)[total], '\0', sizeof(nt_forms_struct) );
99 if ( parse_form_entry(line, &(*list)[total] ) )
106 file_lines_free(lines);
111 /****************************************************************************
112 write a form struct list
113 ****************************************************************************/
114 int write_ntforms(nt_forms_struct **list, int number)
118 char *file = lp_nt_forms();
124 DEBUG(106,("write_ntforms\n"));
127 if((fd = sys_open(file, O_WRONLY|O_CREAT|O_EXCL, 0644)) == -1)
129 DEBUG(0, ("write_ntforms: Cannot create forms file [%s]. Error was %s\n", file, strerror(errno) ));
133 for (i=0; i<number;i++)
136 fdprintf(fd,"%s:%d:%d:%d:%d:%d:%d:%d\n", (*list)[i].name,
137 (*list)[i].flag, (*list)[i].width, (*list)[i].length,
138 (*list)[i].left, (*list)[i].top, (*list)[i].right, (*list)[i].bottom);
140 DEBUGADD(107,("adding entry [%s]\n", (*list)[i].name));
144 DEBUGADD(106,("closing file\n"));
148 /****************************************************************************
149 add a form struct at the end of the list
150 ****************************************************************************/
151 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
158 * NT tries to add forms even when
159 * they are already in the base
160 * only update the values if already present
165 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
166 for (n=0; n<*count && update==False; n++)
168 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
170 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
177 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
179 unistr2_to_ascii((*list)[n].name, &(form->name), sizeof((*list)[n].name)-1);
183 (*list)[n].flag=form->flags;
184 (*list)[n].width=form->size_x;
185 (*list)[n].length=form->size_y;
186 (*list)[n].left=form->left;
187 (*list)[n].top=form->top;
188 (*list)[n].right=form->right;
189 (*list)[n].bottom=form->bottom;
194 /****************************************************************************
196 ****************************************************************************/
197 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
201 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
203 DEBUG(106, ("[%s]\n", form_name));
204 for (n=0; n<count; n++)
206 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
207 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
211 if (n==count) return;
213 (*list)[n].flag=form->flags;
214 (*list)[n].width=form->size_x;
215 (*list)[n].length=form->size_y;
216 (*list)[n].left=form->left;
217 (*list)[n].top=form->top;
218 (*list)[n].right=form->right;
219 (*list)[n].bottom=form->bottom;
222 /****************************************************************************
223 get the nt drivers list
225 open the directory and look-up the matching names
226 ****************************************************************************/
227 int get_ntdrivers(fstring **list, char *architecture)
237 DEBUG(105,("Getting the driver list from directory: [%s]\n", lp_nt_drivers_file()));
240 dirp = opendir(lp_nt_drivers_file());
244 DEBUG(0,("Error opening driver directory [%s]\n",lp_nt_drivers_file()));
248 get_short_archi(short_archi, architecture);
249 slprintf(name_match, sizeof(name_match)-1, "NTdriver_%s_", short_archi);
250 match_len=strlen(name_match);
252 while ((dpname = readdirname(dirp)) != NULL)
254 if (strncmp(dpname, name_match, match_len)==0)
256 DEBUGADD(107,("Found: [%s]\n", dpname));
258 fstrcpy(driver_name, dpname+match_len);
259 all_string_sub(driver_name, "#", "/", 0);
261 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
264 StrnCpy((*list)[total], driver_name, strlen(driver_name));
265 DEBUGADD(106,("Added: [%s]\n", driver_name));
274 /****************************************************************************
275 function to do the mapping between the long architecture name and
277 ****************************************************************************/
278 void get_short_archi(char *short_archi, char *long_archi)
285 struct table archi_table[]=
287 {"Windows 4.0", "WIN40" },
288 {"Windows NT x86", "W32X86" },
289 {"Windows NT R4000", "W32mips" },
290 {"Windows NT Alpha_AXP", "W32alpha" },
291 {"Windows NT PowerPC", "W32ppc" },
297 DEBUG(107,("Getting architecture dependant directory\n"));
300 } while ( (archi_table[i].long_archi!=NULL ) && strncmp(long_archi, archi_table[i].long_archi, strlen(long_archi)) );
302 if (archi_table[i].long_archi==NULL)
304 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
306 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
308 DEBUGADD(108,("index: [%d]\n", i));
309 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
310 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
313 /****************************************************************************
314 ****************************************************************************/
315 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
319 fstring architecture;
321 char **dependentfiles;
323 /* create a file in the dir lp_nt_driver_file */
324 /* with the full printer DRIVER name */
325 /* eg: "/usr/local/samba/lib/NTdriver_HP LaserJet 6MP" */
326 /* each name is really defining an *unique* printer model */
327 /* I don't want to mangle the name to find it back when enumerating */
329 /* il faut substituer les / par 1 autre caractere d'abord */
330 /* dans le nom de l'imprimante par un # ???*/
332 StrnCpy(driver_name, driver->name, sizeof(driver_name)-1);
334 all_string_sub(driver_name, "/", "#", 0);
336 get_short_archi(architecture, driver->environment);
338 slprintf(file, sizeof(file)-1, "%s/NTdriver_%s_%s",
339 lp_nt_drivers_file(), architecture, driver_name);
342 if((fd = sys_open(file, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644)) == -1)
344 DEBUG(0, ("add_a_printer_driver_3: Cannot create driver file [%s]. Error was %s\n", file, strerror(errno) ));
349 * cversion must be 2.
350 * when adding a printer ON the SERVER
351 * rpcAddPrinterDriver defines it to zero
358 fdprintf(fd, "version: %d\n", driver->cversion);
359 fdprintf(fd, "name: %s\n", driver->name);
360 fdprintf(fd, "environment: %s\n", driver->environment);
361 fdprintf(fd, "driverpath: %s\n", driver->driverpath);
362 fdprintf(fd, "datafile: %s\n", driver->datafile);
363 fdprintf(fd, "configfile: %s\n", driver->configfile);
364 fdprintf(fd, "helpfile: %s\n", driver->helpfile);
365 fdprintf(fd, "monitorname: %s\n", driver->monitorname);
366 fdprintf(fd, "defaultdatatype: %s\n", driver->defaultdatatype);
368 /* and the dependants files */
370 dependentfiles=driver->dependentfiles;
372 while ( **dependentfiles != '\0' )
374 fdprintf(fd, "dependentfile: %s\n", *dependentfiles);
382 /****************************************************************************
383 ****************************************************************************/
384 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
390 fstring architecture;
391 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info = NULL;
395 char **dependentfiles=NULL;
398 * replace all the / by # in the driver name
399 * get the short architecture name
400 * construct the driver file name
402 StrnCpy(driver_name, in_prt, sizeof(driver_name)-1);
403 all_string_sub(driver_name, "/", "#", 0);
405 get_short_archi(architecture, in_arch);
407 slprintf(file, sizeof(file)-1, "%s/NTdriver_%s_%s",
408 lp_nt_drivers_file(), architecture, driver_name);
410 lines = file_lines_load(file, NULL);
413 DEBUG(2, ("get_a_printer_driver_3: Cannot open printer driver file [%s]. Error was %s\n", file, strerror(errno) ));
417 /* the file exists, allocate some memory */
418 if((info=(NT_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(NT_PRINTER_DRIVER_INFO_LEVEL_3))) == NULL)
423 for (lcount=0; lines[lcount]; lcount++) {
424 char *line = lines[lcount];
425 v=strncpyn(p, line, sizeof(p), ':');
428 DEBUG(1, ("malformed printer driver entry (no :)\n"));
434 trim_string(v, " ", NULL);
435 trim_string(v, NULL, " ");
436 trim_string(v, NULL, "\n");
437 /* don't check if v==NULL as an empty arg is valid */
439 if (!strncmp(p, "version", strlen("version")))
440 info->cversion=atoi(v);
442 if (!strncmp(p, "name", strlen("name")))
443 StrnCpy(info->name, v, strlen(v));
445 if (!strncmp(p, "environment", strlen("environment")))
446 StrnCpy(info->environment, v, strlen(v));
448 if (!strncmp(p, "driverpath", strlen("driverpath")))
449 StrnCpy(info->driverpath, v, strlen(v));
451 if (!strncmp(p, "datafile", strlen("datafile")))
452 StrnCpy(info->datafile, v, strlen(v));
454 if (!strncmp(p, "configfile", strlen("configfile")))
455 StrnCpy(info->configfile, v, strlen(v));
457 if (!strncmp(p, "helpfile", strlen("helpfile")))
458 StrnCpy(info->helpfile, v, strlen(v));
460 if (!strncmp(p, "monitorname", strlen("monitorname")))
461 StrnCpy(info->monitorname, v, strlen(v));
463 if (!strncmp(p, "defaultdatatype", strlen("defaultdatatype")))
464 StrnCpy(info->defaultdatatype, v, strlen(v));
466 if (!strncmp(p, "dependentfile", strlen("dependentfile")))
468 if((dependentfiles=(char **)Realloc(dependentfiles, sizeof(char *)*(i+1))) == NULL)
471 if((dependentfiles[i]=(char *)malloc( sizeof(char)* (strlen(v)+1) )) == NULL)
474 StrnCpy(dependentfiles[i], v, strlen(v) );
479 file_lines_free(lines);
481 dependentfiles=(char **)Realloc(dependentfiles, sizeof(char *)*(i+1));
482 dependentfiles[i]=(char *)malloc( sizeof(char) );
483 *dependentfiles[i]='\0';
485 info->dependentfiles=dependentfiles;
494 file_lines_free(lines);
500 if(dependentfiles[i])
501 free(dependentfiles[i]);
503 free(dependentfiles);
509 /****************************************************************************
510 debugging function, dump at level 6 the struct in the logs
511 ****************************************************************************/
512 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
515 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
516 char **dependentfiles;
518 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
524 if (driver.info_3 == NULL)
529 DEBUGADD(106,("version:[%d]\n", info3->cversion));
530 DEBUGADD(106,("name:[%s]\n", info3->name));
531 DEBUGADD(106,("environment:[%s]\n", info3->environment));
532 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
533 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
534 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
535 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
536 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
537 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
539 dependentfiles=info3->dependentfiles;
541 while ( **dependentfiles != '\0' )
543 DEBUGADD(106,("dependentfile:[%s]\n", *dependentfiles));
551 DEBUGADD(1,("Level not implemented\n"));
559 /****************************************************************************
560 ****************************************************************************/
561 static void add_a_devicemode(NT_DEVICEMODE *nt_devmode, int fd)
565 fdprintf(fd, "formname: %s\n", nt_devmode->formname);
566 fdprintf(fd, "specversion: %d\n", nt_devmode->specversion);
567 fdprintf(fd, "driverversion: %d\n", nt_devmode->driverversion);
568 fdprintf(fd, "size: %d\n", nt_devmode->size);
569 fdprintf(fd, "driverextra: %d\n", nt_devmode->driverextra);
570 fdprintf(fd, "fields: %d\n", nt_devmode->fields);
571 fdprintf(fd, "orientation: %d\n", nt_devmode->orientation);
572 fdprintf(fd, "papersize: %d\n", nt_devmode->papersize);
573 fdprintf(fd, "paperlength: %d\n", nt_devmode->paperlength);
574 fdprintf(fd, "paperwidth: %d\n", nt_devmode->paperwidth);
575 fdprintf(fd, "scale: %d\n", nt_devmode->scale);
576 fdprintf(fd, "copies: %d\n", nt_devmode->copies);
577 fdprintf(fd, "defaultsource: %d\n", nt_devmode->defaultsource);
578 fdprintf(fd, "printquality: %d\n", nt_devmode->printquality);
579 fdprintf(fd, "color: %d\n", nt_devmode->color);
580 fdprintf(fd, "duplex: %d\n", nt_devmode->duplex);
581 fdprintf(fd, "yresolution: %d\n", nt_devmode->yresolution);
582 fdprintf(fd, "ttoption: %d\n", nt_devmode->ttoption);
583 fdprintf(fd, "collate: %d\n", nt_devmode->collate);
584 fdprintf(fd, "icmmethod: %d\n", nt_devmode->icmmethod);
585 fdprintf(fd, "icmintent: %d\n", nt_devmode->icmintent);
586 fdprintf(fd, "mediatype: %d\n", nt_devmode->mediatype);
587 fdprintf(fd, "dithertype: %d\n", nt_devmode->dithertype);
589 if (nt_devmode->private != NULL)
591 fdprintf(fd, "private: ");
592 for (i=0; i<nt_devmode->driverextra; i++)
593 fdprintf(fd, "%02X", nt_devmode->private[i]);
598 /****************************************************************************
599 ****************************************************************************/
600 static void save_specifics(NT_PRINTER_PARAM *param, int fd)
604 while (param != NULL)
606 fdprintf(fd, "specific: %s#%d#%d#", param->value, param->type, param->data_len);
608 for (i=0; i<param->data_len; i++)
609 fdprintf(fd, "%02X", param->data[i]);
618 /****************************************************************************
619 delete a printer - this just deletes the printer info file, any open
620 handles are not affected
621 ****************************************************************************/
622 uint32 del_a_printer(char *portname)
626 slprintf(file, sizeof(file), "%s/NTprinter_%s",
627 lp_nt_drivers_file(), portname);
628 if (unlink(file) != 0) return 2;
632 /****************************************************************************
633 ****************************************************************************/
634 static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
638 fstring printer_name;
639 NT_DEVICEMODE *nt_devmode;
642 * JFM: one day I'll forget.
643 * below that's info->portname because that's the SAMBA sharename
644 * and I made NT 'thinks' it's the portname
645 * the info->sharename is the thing you can name when you add a printer
646 * that's the short-name when you create shared printer for 95/98
647 * So I've made a limitation in SAMBA: you can only have 1 printer model
648 * behind a SAMBA share.
652 StrnCpy(printer_name, info->portname, sizeof(printer_name)-1);
654 slprintf(file, sizeof(file)-1, "%s/NTprinter_%s",
655 lp_nt_drivers_file(), printer_name);
657 /* create a file in the dir lp_nt_driver_file */
658 /* with the full printer name */
659 /* eg: "/usr/local/samba/lib/NTprinter_HP LaserJet 6MP" */
660 /* each name is really defining an *unique* printer model */
661 /* I don't want to mangle the name to find it back when enumerating */
664 if((fd = sys_open(file, O_WRONLY|O_CREAT|O_EXCL, 0644)) == -1)
666 DEBUG(0, ("add_a_printer_2: Cannot create printer file [%s]. Error was %s\n", file, strerror(errno) ));
670 fdprintf(fd, "attributes: %d\n", info->attributes);
671 fdprintf(fd, "priority: %d\n", info->priority);
672 fdprintf(fd, "default_priority: %d\n", info->default_priority);
673 fdprintf(fd, "starttime: %d\n", info->starttime);
674 fdprintf(fd, "untiltime: %d\n", info->untiltime);
675 fdprintf(fd, "status: %d\n", info->status);
676 fdprintf(fd, "cjobs: %d\n", info->cjobs);
677 fdprintf(fd, "averageppm: %d\n", info->averageppm);
678 fdprintf(fd, "changeid: %d\n", info->changeid);
679 fdprintf(fd, "c_setprinter: %d\n", info->c_setprinter);
680 fdprintf(fd, "setuptime: %d\n", (int)info->setuptime);
683 * in addprinter: no servername and the printer is the name
684 * in setprinter: servername is \\server
685 * and printer is \\server\\printer
687 * Samba manages only local printers.
688 * we currently don't support things like path=\\other_server\printer
691 if (info->servername[0]!='\0')
693 trim_string(info->printername, info->servername, NULL);
694 trim_string(info->printername, "\\", NULL);
695 info->servername[0]='\0';
698 fdprintf(fd, "servername: %s\n", info->servername);
699 fdprintf(fd, "printername: %s\n", info->printername);
700 fdprintf(fd, "sharename: %s\n", info->sharename);
701 fdprintf(fd, "portname: %s\n", info->portname);
702 fdprintf(fd, "drivername: %s\n", info->drivername);
703 fdprintf(fd, "location: %s\n", info->location);
704 fdprintf(fd, "sepfile: %s\n", info->sepfile);
705 fdprintf(fd, "printprocessor: %s\n", info->printprocessor);
706 fdprintf(fd, "datatype: %s\n", info->datatype);
707 fdprintf(fd, "parameters: %s\n", info->parameters);
709 /* store the devmode and the private part if it exist */
710 nt_devmode=info->devmode;
711 if (nt_devmode!=NULL)
713 add_a_devicemode(nt_devmode, fd);
716 /* and store the specific parameters */
717 if (info->specific != NULL)
719 save_specifics(info->specific, fd);
727 /****************************************************************************
728 fill a NT_PRINTER_PARAM from a text file
730 used when reading from disk.
731 ****************************************************************************/
732 static BOOL dissect_and_fill_a_param(NT_PRINTER_PARAM *param, char *v)
737 DEBUG(105,("dissect_and_fill_a_param\n"));
739 tok[count] = strtok(v,"#");
742 while ( ((tok[count] = strtok(NULL,"#")) != NULL ) && count<4)
747 StrnCpy(param->value, tok[0], sizeof(param->value)-1);
748 param->type=atoi(tok[1]);
749 param->data_len=atoi(tok[2]);
750 if((param->data=(uint8 *)malloc(param->data_len * sizeof(uint8))) == NULL)
752 strhex_to_str(param->data, 2*(param->data_len), tok[3]);
755 DEBUGADD(105,("value:[%s], len:[%d]\n", param->value, param->data_len));
759 /****************************************************************************
760 fill a NT_PRINTER_PARAM from a text file
762 used when reading from disk.
763 ****************************************************************************/
764 void dump_a_param(NT_PRINTER_PARAM *param)
766 DEBUG(105,("dump_a_param\n"));
767 DEBUGADD(106,("value [%s]\n", param->value));
768 DEBUGADD(106,("type [%d]\n", param->type));
769 DEBUGADD(106,("data len [%d]\n", param->data_len));
772 /****************************************************************************
773 ****************************************************************************/
774 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
776 NT_PRINTER_PARAM *current;
778 DEBUG(108,("add_a_specific_param\n"));
782 if (info_2->specific == NULL)
784 info_2->specific=param;
788 current=info_2->specific;
789 while (current->next != NULL) {
790 current=current->next;
797 /****************************************************************************
798 ****************************************************************************/
799 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
801 NT_PRINTER_PARAM *current;
802 NT_PRINTER_PARAM *previous;
804 current=info_2->specific;
807 if (current==NULL) return (False);
809 if ( !strcmp(current->value, param->value) &&
810 (strlen(current->value)==strlen(param->value)) )
812 DEBUG(109,("deleting first value\n"));
813 info_2->specific=current->next;
814 safe_free(current->data);
816 DEBUG(109,("deleted first value\n"));
820 current=previous->next;
822 while ( current!=NULL )
824 if (!strcmp(current->value, param->value) &&
825 strlen(current->value)==strlen(param->value) )
827 DEBUG(109,("deleting current value\n"));
828 previous->next=current->next;
830 DEBUG(109,("deleted current value\n"));
834 previous=previous->next;
835 current=current->next;
840 /****************************************************************************
841 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
842 ****************************************************************************/
844 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
846 NT_PRINTER_PARAM *param = *param_ptr;
851 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
860 /****************************************************************************
861 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
862 ****************************************************************************/
864 static void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
866 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
868 if(nt_devmode == NULL)
871 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
873 if(nt_devmode->private)
874 free(nt_devmode->private);
880 /****************************************************************************
881 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
882 ****************************************************************************/
884 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
886 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
887 NT_PRINTER_PARAM *param_ptr;
892 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
894 free_nt_devicemode(&info->devmode);
896 for(param_ptr = info->specific; param_ptr; ) {
897 NT_PRINTER_PARAM *tofree = param_ptr;
899 param_ptr = param_ptr->next;
900 free_nt_printer_param(&tofree);
907 /****************************************************************************
908 ****************************************************************************/
909 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
912 fstring printer_name;
913 NT_PRINTER_INFO_LEVEL_2 *info = NULL;
914 NT_DEVICEMODE *nt_devmode = NULL;
915 NT_PRINTER_PARAM *param = NULL;
922 * the sharename argument is the SAMBA sharename
924 StrnCpy(printer_name, sharename, sizeof(printer_name)-1);
926 slprintf(file, sizeof(file)-1, "%s/NTprinter_%s",
927 lp_nt_drivers_file(), printer_name);
929 lines = file_lines_load(file,NULL);
931 DEBUG(2, ("get_a_printer_2: Cannot open printer file [%s]. Error was %s\n", file, strerror(errno) ));
935 /* the file exists, allocate some memory */
936 if((info=(NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2))) == NULL)
941 if((nt_devmode=(NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE))) == NULL)
944 ZERO_STRUCTP(nt_devmode);
945 init_devicemode(nt_devmode);
947 info->devmode=nt_devmode;
949 for (i=0; lines[i]; i++) {
950 char *line = lines[i];
952 if (!*line) continue;
954 v=strncpyn(p, line, sizeof(p), ':');
957 DEBUG(1, ("malformed printer entry (no `:')\n"));
958 DEBUGADD(2, ("line [%s]\n", line));
964 trim_string(v, " ", NULL);
965 trim_string(v, NULL, " ");
966 trim_string(v, NULL, "\n");
968 /* don't check if v==NULL as an empty arg is valid */
970 DEBUGADD(115, ("[%s]:[%s]\n", p, v));
973 * The PRINTER_INFO_2 fields
976 if (!strncmp(p, "attributes", strlen("attributes")))
977 info->attributes=atoi(v);
979 if (!strncmp(p, "priority", strlen("priority")))
980 info->priority=atoi(v);
982 if (!strncmp(p, "default_priority", strlen("default_priority")))
983 info->default_priority=atoi(v);
985 if (!strncmp(p, "starttime", strlen("starttime")))
986 info->starttime=atoi(v);
988 if (!strncmp(p, "untiltime", strlen("untiltime")))
989 info->untiltime=atoi(v);
991 if (!strncmp(p, "status", strlen("status")))
992 info->status=atoi(v);
994 if (!strncmp(p, "cjobs", strlen("cjobs")))
997 if (!strncmp(p, "averageppm", strlen("averageppm")))
998 info->averageppm=atoi(v);
1000 if (!strncmp(p, "changeid", strlen("changeid")))
1001 info->changeid=atoi(v);
1003 if (!strncmp(p, "c_setprinter", strlen("c_setprinter")))
1004 info->c_setprinter=atoi(v);
1006 if (!strncmp(p, "setuptime", strlen("setuptime")))
1007 info->setuptime=atoi(v);
1009 if (!strncmp(p, "servername", strlen("servername")))
1010 StrnCpy(info->servername, v, strlen(v));
1012 if (!strncmp(p, "printername", strlen("printername")))
1013 StrnCpy(info->printername, v, strlen(v));
1015 if (!strncmp(p, "sharename", strlen("sharename")))
1016 StrnCpy(info->sharename, v, strlen(v));
1018 if (!strncmp(p, "portname", strlen("portname")))
1019 StrnCpy(info->portname, v, strlen(v));
1021 if (!strncmp(p, "drivername", strlen("drivername")))
1022 StrnCpy(info->drivername, v, strlen(v));
1024 if (!strncmp(p, "location", strlen("location")))
1025 StrnCpy(info->location, v, strlen(v));
1027 if (!strncmp(p, "sepfile", strlen("sepfile")))
1028 StrnCpy(info->sepfile, v, strlen(v));
1030 if (!strncmp(p, "printprocessor", strlen("printprocessor")))
1031 StrnCpy(info->printprocessor, v, strlen(v));
1033 if (!strncmp(p, "datatype", strlen("datatype")))
1034 StrnCpy(info->datatype, v, strlen(v));
1036 if (!strncmp(p, "parameters", strlen("parameters")))
1037 StrnCpy(info->parameters, v, strlen(v));
1040 * The DEVICEMODE fields
1043 if (!strncmp(p, "formname", strlen("formname")))
1044 StrnCpy(nt_devmode->formname, v, strlen(v));
1046 if (!strncmp(p, "specversion", strlen("specversion")))
1047 nt_devmode->specversion=atoi(v);
1049 if (!strncmp(p, "driverversion", strlen("driverversion")))
1050 nt_devmode->driverversion=atoi(v);
1052 if (!strncmp(p, "size", strlen("size")))
1053 nt_devmode->size=atoi(v);
1055 if (!strncmp(p, "driverextra", strlen("driverextra")))
1056 nt_devmode->driverextra=atoi(v);
1058 if (!strncmp(p, "fields", strlen("fields")))
1059 nt_devmode->fields=atoi(v);
1061 if (!strncmp(p, "orientation", strlen("orientation")))
1062 nt_devmode->orientation=atoi(v);
1064 if (!strncmp(p, "papersize", strlen("papersize")))
1065 nt_devmode->papersize=atoi(v);
1067 if (!strncmp(p, "paperlength", strlen("paperlength")))
1068 nt_devmode->paperlength=atoi(v);
1070 if (!strncmp(p, "paperwidth", strlen("paperwidth")))
1071 nt_devmode->paperwidth=atoi(v);
1073 if (!strncmp(p, "scale", strlen("scale")))
1074 nt_devmode->scale=atoi(v);
1076 if (!strncmp(p, "copies", strlen("copies")))
1077 nt_devmode->copies=atoi(v);
1079 if (!strncmp(p, "defaultsource", strlen("defaultsource")))
1080 nt_devmode->defaultsource=atoi(v);
1082 if (!strncmp(p, "printquality", strlen("printquality")))
1083 nt_devmode->printquality=atoi(v);
1085 if (!strncmp(p, "color", strlen("color")))
1086 nt_devmode->color=atoi(v);
1088 if (!strncmp(p, "duplex", strlen("duplex")))
1089 nt_devmode->duplex=atoi(v);
1091 if (!strncmp(p, "yresolution", strlen("yresolution")))
1092 nt_devmode->yresolution=atoi(v);
1094 if (!strncmp(p, "ttoption", strlen("ttoption")))
1095 nt_devmode->ttoption=atoi(v);
1097 if (!strncmp(p, "collate", strlen("collate")))
1098 nt_devmode->collate=atoi(v);
1100 if (!strncmp(p, "icmmethod", strlen("icmmethod")))
1101 nt_devmode->icmmethod=atoi(v);
1103 if (!strncmp(p, "icmintent", strlen("icmintent")))
1104 nt_devmode->icmintent=atoi(v);
1106 if (!strncmp(p, "mediatype", strlen("mediatype")))
1107 nt_devmode->mediatype=atoi(v);
1109 if (!strncmp(p, "dithertype", strlen("dithertype")))
1110 nt_devmode->dithertype=atoi(v);
1112 if (!strncmp(p, "private", strlen("private")))
1114 if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra*sizeof(uint8))) == NULL)
1117 strhex_to_str(nt_devmode->private, 2*nt_devmode->driverextra, v);
1122 if (!strncmp(p, "specific", strlen("specific")))
1124 if((param=(NT_PRINTER_PARAM *)malloc(sizeof(NT_PRINTER_PARAM))) == NULL)
1127 ZERO_STRUCTP(param);
1129 if(!dissect_and_fill_a_param(param, v))
1132 dump_a_param(param);
1134 add_a_specific_param(info, param);
1138 file_lines_free(lines);
1147 file_lines_free(lines);
1149 free_nt_printer_info_level_2(&info);
1153 /****************************************************************************
1154 debugging function, dump at level 6 the struct in the logs
1155 ****************************************************************************/
1156 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1159 NT_PRINTER_INFO_LEVEL_2 *info2;
1161 DEBUG(106,("Dumping printer at level [%d]\n", level));
1167 if (printer.info_2 == NULL)
1171 info2=printer.info_2;
1173 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1174 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1175 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1176 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1177 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1178 DEBUGADD(106,("status:[%d]\n", info2->status));
1179 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1180 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1181 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1182 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1183 DEBUGADD(106,("setuptime:[%d]\n", (int)info2->setuptime));
1185 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1186 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1187 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1188 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1189 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1190 DEBUGADD(106,("location:[%s]\n", info2->location));
1191 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1192 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1193 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1194 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1200 DEBUGADD(1,("Level not implemented\n"));
1209 * The function below are the high level ones.
1210 * only those ones must be called from the spoolss code.
1215 /****************************************************************************
1216 ****************************************************************************/
1217 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1221 dump_a_printer(printer, level);
1227 success=add_a_printer_2(printer.info_2);
1238 /****************************************************************************
1239 ****************************************************************************/
1240 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level, fstring sharename)
1244 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1250 printer->info_2=NULL;
1251 success=get_a_printer_2(&(printer->info_2), sharename);
1259 dump_a_printer(*printer, level);
1261 DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1266 /****************************************************************************
1267 ****************************************************************************/
1268 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1271 DEBUG(104,("freeing a printer at level [%d]\n", level));
1277 if (printer.info_2 != NULL)
1279 free_nt_printer_info_level_2(&printer.info_2);
1295 /****************************************************************************
1296 ****************************************************************************/
1297 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1300 DEBUG(104,("adding a printer at level [%d]\n", level));
1301 dump_a_printer_driver(driver, level);
1307 success=add_a_printer_driver_3(driver.info_3);
1317 /****************************************************************************
1318 ****************************************************************************/
1319 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
1320 fstring printername, fstring architecture)
1328 success=get_a_printer_driver_3(&(driver->info_3),
1338 dump_a_printer_driver(*driver, level);
1342 /****************************************************************************
1343 ****************************************************************************/
1344 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1347 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1348 char **dependentfiles;
1354 if (driver.info_3 != NULL)
1356 info3=driver.info_3;
1357 dependentfiles=info3->dependentfiles;
1359 while ( **dependentfiles != '\0' )
1361 free (*dependentfiles);
1365 /* the last one (1 char !) */
1366 free (*dependentfiles);
1368 dependentfiles=info3->dependentfiles;
1369 free (dependentfiles);
1387 /****************************************************************************
1388 ****************************************************************************/
1389 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
1390 fstring value, uint8 **data, uint32 *type, uint32 *len)
1392 /* right now that's enough ! */
1393 NT_PRINTER_PARAM *param;
1396 param=printer.info_2->specific;
1398 while (param != NULL && i <= param_index)
1407 /* exited because it exist */
1409 StrnCpy(value, param->value, sizeof(fstring)-1);
1410 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1413 memcpy(*data, param->data, param->data_len);
1414 *len=param->data_len;
1418 /****************************************************************************
1419 ****************************************************************************/
1420 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
1421 fstring value, uint8 **data, uint32 *type, uint32 *len)
1423 /* right now that's enough ! */
1424 NT_PRINTER_PARAM *param;
1426 DEBUG(105, ("get_specific_param\n"));
1428 param=printer.info_2->specific;
1430 while (param != NULL)
1432 if ( !strcmp(value, param->value)
1433 && strlen(value)==strlen(param->value))
1439 DEBUG(106, ("found one param\n"));
1442 /* exited because it exist */
1445 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1448 memcpy(*data, param->data, param->data_len);
1449 *len=param->data_len;
1451 DEBUG(106, ("exit of get_specific_param:true\n"));
1454 DEBUG(106, ("exit of get_specific_param:false\n"));
1458 /****************************************************************************
1459 ****************************************************************************/
1460 void init_devicemode(NT_DEVICEMODE *nt_devmode)
1463 * should I init this ones ???
1464 nt_devmode->devicename
1466 fstrcpy(nt_devmode->formname, "A4");
1468 nt_devmode->specversion = 0x0401;
1469 nt_devmode->driverversion = 0x0400;
1470 nt_devmode->size = 0x00DC;
1471 nt_devmode->driverextra = 0x0000;
1472 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
1473 DEFAULTSOURCE | COPIES | SCALE |
1474 PAPERSIZE | ORIENTATION;
1475 nt_devmode->orientation = 1;
1476 nt_devmode->papersize = PAPER_A4;
1477 nt_devmode->paperlength = 0;
1478 nt_devmode->paperwidth = 0;
1479 nt_devmode->scale = 0x64;
1480 nt_devmode->copies = 01;
1481 nt_devmode->defaultsource = BIN_FORMSOURCE;
1482 nt_devmode->printquality = 0x0258;
1483 nt_devmode->color = COLOR_MONOCHROME;
1484 nt_devmode->duplex = DUP_SIMPLEX;
1485 nt_devmode->yresolution = 0;
1486 nt_devmode->ttoption = TT_SUBDEV;
1487 nt_devmode->collate = COLLATE_FALSE;
1488 nt_devmode->icmmethod = 0;
1489 nt_devmode->icmintent = 0;
1490 nt_devmode->mediatype = 0;
1491 nt_devmode->dithertype = 0;
1493 /* non utilisés par un driver d'imprimante */
1494 nt_devmode->logpixels = 0;
1495 nt_devmode->bitsperpel = 0;
1496 nt_devmode->pelswidth = 0;
1497 nt_devmode->pelsheight = 0;
1498 nt_devmode->displayflags = 0;
1499 nt_devmode->displayfrequency = 0;
1500 nt_devmode->reserved1 = 0;
1501 nt_devmode->reserved2 = 0;
1502 nt_devmode->panningwidth = 0;
1503 nt_devmode->panningheight = 0;
1505 nt_devmode->private=NULL;
1511 1: level not implemented
1512 2: file doesn't exist
1513 3: can't allocate memory
1514 4: can't free memory
1515 5: non existant struct
1519 A printer and a printer driver are 2 different things.
1520 NT manages them separatelly, Samba does the same.
1521 Why ? Simply because it's easier and it makes sense !
1523 Now explanation: You have 3 printers behind your samba server,
1524 2 of them are the same make and model (laser A and B). But laser B
1525 has an 3000 sheet feeder and laser A doesn't such an option.
1526 Your third printer is an old dot-matrix model for the accounting :-).
1528 If the /usr/local/samba/lib directory (default dir), you will have
1529 5 files to describe all of this.
1531 3 files for the printers (1 by printer):
1534 NTprinter_accounting
1535 2 files for the drivers (1 for the laser and 1 for the dot matrix)
1536 NTdriver_printer model X
1537 NTdriver_printer model Y
1539 jfm: I should use this comment for the text file to explain
1540 same thing for the forms BTW.
1541 Je devrais mettre mes commentaires en francais, ca serait mieux :-)