add WITH_SENDFILE profiling data (from Pierre Belanger)
[Samba.git] / source / utils / make_printerdef.c
blob621dff5b1037f460d7e8bda9095031b76ffbf9c8
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Create printer definition files.
6 Copyright (C) Jean-Francois.Micouleau@utc.fr, 10/26/97 - 1998
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.
23 #include "includes.h"
26 #define DEBUGIT
29 char *files_to_copy;
30 char *driverfile, *datafile, *helpfile, *languagemonitor, *datatype, *vendorsetup;
31 char buffer[50][sizeof(pstring)];
32 char sbuffer[50][sizeof(pstring)];
33 char sub_dir[50][2][sizeof(pstring)];
35 static void usage(char *name)
37 fprintf(stderr,"%s: printer.def \"Printer Name\"\n", name);
40 static char *myfgets(char *s, int n, FILE *stream)
42 char *LString1;
43 char *LString2;
44 char *temp;
45 pstring String;
46 pstring NewString;
47 int i;
49 fgets(s,n,stream);
50 while ((LString1 = strchr(s,'%')) != NULL) {
51 if (!(LString2 = strchr(LString1+1,'%'))) break;
52 *LString2 = '\0';
53 pstrcpy(String,LString1+1);
54 i = 0;
55 while(*sbuffer[i]!='\0') {
56 if (strncmp(sbuffer[i],String,strlen(String))==0)
58 pstrcpy(String,sbuffer[i]);
59 if ((temp = strchr(String,'=')) != NULL) ++temp;
60 pstrcpy(String,temp);
61 break;
63 i++;
65 *LString1 = '\0';
66 pstrcpy(NewString,s);
67 pstrcat(NewString,String);
68 pstrcat(NewString,LString2+1);
69 pstrcpy(s, NewString);
71 return(s);
75 This function split a line in two parts
76 on both side of the equal sign
77 "entry=value"
79 static char *scan(char *chaine,char **entry)
81 char *value;
82 char *temp;
83 int i=0;
85 *entry=(char *)malloc(sizeof(pstring));
86 value=(char *)malloc(sizeof(pstring));
88 if(*entry == NULL || value == NULL) {
89 fprintf(stderr,"scan: malloc fail !\n");
90 exit(1);
93 pstrcpy(*entry,chaine);
94 temp=chaine;
95 while( temp[i]!='=' && temp[i]!='\0') {
96 i++;
98 (*entry)[i]='\0';
99 if (temp[i]!='\0') {
100 i++;
102 while( temp[i]==' ' && temp[i]!='\0') {
103 i++;
105 pstrcpy(value,temp+i);
106 return (value);
109 static void build_subdir(void)
111 int i=0;
112 int j=0;
113 char *entry;
114 char *data;
116 while (*buffer[i]!='\0') {
117 data=scan(buffer[i],&entry);
118 #ifdef DEBUGIT
119 fprintf(stderr,"\tentry=data %s:%s\n",entry,data);
120 #endif
121 j = strlen(entry);
122 while (j) {
123 if (entry[j-1] != ' ') break;
124 j--;
126 entry[j] = '\0';
128 if (strncmp(data,"11",2)==0) {
129 pstrcpy(sub_dir[i][0],entry);
130 pstrcpy(sub_dir[i][1],"");
132 if (strncmp(data,"23",2)==0) {
133 pstrcpy(sub_dir[i][0],entry);
134 pstrcpy(sub_dir[i][1],"color\\");
136 #ifdef DEBUGIT
137 fprintf(stderr,"\tsubdir %s:%s\n",sub_dir[i][0],sub_dir[i][1]);
138 #endif
139 i++;
144 Lockup Strings entry in a file
145 Return all the lines between the entry and the next one or the end of file
146 An entry is something between braces.
148 static void lookup_strings(FILE *fichier)
150 int found=0,pointeur=0,i=0;
151 char *temp,*temp2;
153 temp=(char *)malloc(sizeof(pstring));
154 temp2=(char *)malloc(sizeof(pstring));
156 if(temp == NULL || temp2 == NULL) {
157 safe_free(temp);
158 safe_free(temp2);
159 fprintf(stderr,"lookup_strings: malloc fail !\n");
160 exit(1);
163 *sbuffer[0]='\0';
165 pstrcpy(temp2,"[Strings]");
167 rewind(fichier);
168 #ifdef DEBUGIT
169 fprintf(stderr,"\tLooking for Strings\n");
170 #endif
172 while (!feof(fichier) && found==0) {
173 *temp='\0';
174 fgets(temp,255,fichier);
175 if (strncmp(temp,temp2,strlen(temp2))==0) found=1;
179 while (!feof(fichier) && found==1) {
180 *temp='\0';
181 fgets(temp,255,fichier);
182 if (*temp=='[') {
183 found=2;
184 *sbuffer[pointeur]='\0';
186 else {
187 pstrcpy(sbuffer[pointeur],temp);
188 i=strlen(sbuffer[pointeur])-1;
189 while (sbuffer[pointeur][i]=='\r' || sbuffer[pointeur][i]=='\n')
190 sbuffer[pointeur][i--]='\0';
191 pointeur++;
195 /* CCMRCF Mod, seg fault or worse if not found */
196 if (pointeur == 0) {
197 fprintf(stderr,"Printer not found\tNo [Strings] block in inf file\n");
198 exit(2);
201 #ifdef DEBUGIT
202 fprintf(stderr,"\t\tFound %d entries\n",pointeur-1);
203 #endif
208 Lockup an entry in a file
209 Return all the lines between the entry and the next one or the end of file
210 An entry is something between braces.
212 static void lookup_entry(FILE *fichier,char *chaine)
214 int found=0,pointeur=0,i=0;
215 char *temp,*temp2;
217 temp=(char *)malloc(sizeof(pstring));
218 temp2=(char *)malloc(sizeof(pstring));
220 if(temp == NULL || temp2 == NULL) {
221 safe_free(temp);
222 safe_free(temp2);
223 fprintf(stderr,"lookup_entry: malloc fail !\n");
224 exit(1);
227 *buffer[0]='\0';
229 pstrcpy(temp2,"[");
230 pstrcat(temp2,chaine);
231 pstrcat(temp2,"]");
233 rewind(fichier);
234 #ifdef DEBUGIT
235 fprintf(stderr,"\tLooking for %s\n",chaine);
236 #endif
238 while (!feof(fichier) && found==0) {
239 *temp='\0';
240 myfgets(temp,255,fichier);
241 if (strncmp(temp,temp2,strlen(temp2))==0) found=1;
245 while (!feof(fichier) && found==1) {
246 *temp='\0';
247 myfgets(temp,255,fichier);
248 if (*temp=='[') {
249 found=2;
250 *buffer[pointeur]='\0';
252 else {
253 pstrcpy(buffer[pointeur],temp);
254 i=strlen(buffer[pointeur])-1;
255 while (buffer[pointeur][i]=='\r' || buffer[pointeur][i]=='\n')
256 buffer[pointeur][i--]='\0';
257 pointeur++;
260 #ifdef DEBUGIT
261 fprintf(stderr,"\t\tFound %d entries\n",pointeur-1);
262 #endif
265 static char *find_desc(FILE *fichier,char *text)
267 char *chaine;
268 char *long_desc;
269 char *short_desc;
270 char *crap = NULL;
271 char *p;
273 int found=0;
275 chaine=(char *)malloc(sizeof(pstring));
276 long_desc=(char *)malloc(sizeof(pstring));
277 short_desc=(char *)malloc(sizeof(pstring));
278 if (!chaine || !long_desc || !short_desc) {
279 safe_free(chaine);
280 safe_free(long_desc);
281 safe_free(short_desc);
282 fprintf(stderr,"find_desc: Unable to malloc memory\n");
283 exit(1);
286 rewind(fichier);
287 while (!feof(fichier) && found==0)
289 myfgets(chaine,255,fichier);
291 long_desc=strtok(chaine,"=");
292 crap=strtok(NULL,",\r");
294 p=long_desc;
295 while(*p!='"' && *p!='\0')
296 p++;
297 if (*p=='"' && *(p+1)!='\0') p++;
298 long_desc=p;
300 if (*p!='\0')
302 p++;
303 while(*p!='\"')
304 p++;
305 *p='\0';
307 if (!strcmp(text,long_desc))
308 found=1;
310 SAFE_FREE(chaine);
311 if (!found || !crap) return(NULL);
312 while(*crap==' ') crap++;
313 pstrcpy(short_desc,crap);
314 return(short_desc);
317 static void scan_copyfiles(FILE *fichier, char *chaine)
319 char *part;
320 char *mpart;
321 int i;
322 pstring direc;
323 #ifdef DEBUGIT
324 fprintf(stderr,"In scan_copyfiles Lookup up of %s\n",chaine);
325 #endif
326 fprintf(stderr,"\nCopy the following files to your printer$ share location:\n");
327 part=strtok(chaine,",");
328 do {
329 /* If the entry start with a @ then it's a file to copy
330 else it's an entry refering to files to copy
331 the main difference is when it's an entry
332 you can have a directory to append before the file name
334 if (*part=='@') {
335 if (strlen(files_to_copy) != 0)
336 pstrcat(files_to_copy,",");
337 pstrcat(files_to_copy,&part[1]);
338 fprintf(stderr,"%s\n",&part[1]);
339 } else {
340 lookup_entry(fichier,part);
341 i=0;
342 pstrcpy(direc,"");
343 while (*sub_dir[i][0]!='\0') {
344 #ifdef DEBUGIT
345 fprintf(stderr,"\tsubdir %s:%s\n",sub_dir[i][0],sub_dir[i][1]);
346 #endif
347 if (strcmp(sub_dir[i][0],part)==0)
348 pstrcpy(direc,sub_dir[i][1]);
349 i++;
351 i=0;
352 while (*buffer[i]!='\0') {
354 * HP inf files have strange entries that this attempts to address
355 * Entries in the Copy sections normally have only a single file name
356 * on each line. I have seen the following format in various HP inf files:
358 * pscript.hlp = pscript.hl_
359 * hpdcmon.dll,hpdcmon.dl_
360 * MSVCRT.DLL,MSVCRT.DL_,,32
361 * ctl3dv2.dll,ctl3dv2.dl_,ctl3dv2.tmp
363 * In the first 2 cases you want the first file name - in the last case
364 * you only want the last file name (at least that is what a Win95
365 * machine sent). In the third case you also want the first file name
366 * (detect by the last component being just a number ?).
367 * This may still be wrong but at least I get the same list
368 * of files as seen on a printer test page.
370 part = strchr(buffer[i],'=');
371 if (part) {
373 * Case (1) eg. pscript.hlp = pscript.hl_ - chop after the first name.
376 *part = '\0';
379 * Now move back to the start and print that.
382 while (--part > buffer[i]) {
383 if ((*part == ' ') || (*part =='\t'))
384 *part = '\0';
385 else
386 break;
388 } else {
389 part = strchr(buffer[i],',');
390 if (part) {
392 * Cases (2-4)
395 if ((mpart = strrchr(part+1,','))!=NULL) {
397 * Second ',' - case 3 or 4.
398 * Check if the last part is just a number,
399 * if so we need the first part.
402 char *endptr = NULL;
403 BOOL isnumber = False;
405 mpart++;
406 (void)strtol(mpart, &endptr, 10);
408 isnumber = ((endptr > mpart) && isdigit(*mpart));
409 if(!isnumber)
410 pstrcpy(buffer[i],mpart+1);
411 else
412 *part = '\0';
413 } else {
414 *part = '\0';
416 while (--part > buffer[i])
417 if ((*part == ' ') || (*part =='\t')) *part = '\0';
418 else break;
421 if (*buffer[i] != ';') {
422 if (strlen(files_to_copy) != 0)
423 pstrcat(files_to_copy,",");
424 pstrcat(files_to_copy,direc);
425 pstrcat(files_to_copy,buffer[i]);
426 fprintf(stderr,"%s%s\n",direc,buffer[i]);
428 i++;
429 } /* end while */
431 part=strtok(NULL,",");
432 if (part) {
433 while( *part ==' ' && *part != '\0') {
434 part++;
437 } while (part!=NULL);
438 fprintf(stderr,"\n");
442 static void scan_short_desc(FILE *fichier, char *short_desc)
444 int i=0;
445 char *temp;
446 char *copyfiles=0,*datasection=0;
448 helpfile=0;
449 languagemonitor=0;
450 vendorsetup=0;
451 datatype="RAW";
452 if((temp=(char *)malloc(sizeof(pstring))) == NULL) {
453 fprintf(stderr, "scan_short_desc: malloc fail !\n");
454 exit(1);
457 driverfile=short_desc;
458 datafile=short_desc;
460 lookup_entry(fichier,short_desc);
462 while(*buffer[i]!='\0') {
463 #ifdef DEBUGIT
464 fprintf(stderr,"\tLookup up of %s\n",buffer[i]);
465 #endif
466 if (strncasecmp(buffer[i],"CopyFiles",9)==0)
467 copyfiles=scan(buffer[i],&temp);
468 else if (strncasecmp(buffer[i],"DataSection",11)==0)
469 datasection=scan(buffer[i],&temp);
470 else if (strncasecmp(buffer[i],"DataFile",8)==0)
471 datafile=scan(buffer[i],&temp);
472 else if (strncasecmp(buffer[i],"DriverFile",10)==0)
473 driverfile=scan(buffer[i],&temp);
474 else if (strncasecmp(buffer[i],"HelpFile",8)==0)
475 helpfile=scan(buffer[i],&temp);
476 else if (strncasecmp(buffer[i],"LanguageMonitor",15)==0)
477 languagemonitor=scan(buffer[i],&temp);
478 else if (strncasecmp(buffer[i],"DefaultDataType",15)==0)
479 datatype=scan(buffer[i],&temp);
480 else if (strncasecmp(buffer[i],"VendorSetup",11)==0)
481 vendorsetup=scan(buffer[i],&temp);
482 i++;
485 if (datasection) {
486 lookup_entry(fichier,datasection);
488 i = 0;
489 while(*buffer[i]!='\0') {
490 #ifdef DEBUGIT
491 fprintf(stderr,"\tLookup up of %s\n",buffer[i]);
492 #endif
493 if (strncasecmp(buffer[i],"CopyFiles",9)==0)
494 copyfiles=scan(buffer[i],&temp);
495 else if (strncasecmp(buffer[i],"DataSection",11)==0)
496 datasection=scan(buffer[i],&temp);
497 else if (strncasecmp(buffer[i],"DataFile",8)==0)
498 datafile=scan(buffer[i],&temp);
499 else if (strncasecmp(buffer[i],"DriverFile",10)==0)
500 driverfile=scan(buffer[i],&temp);
501 else if (strncasecmp(buffer[i],"HelpFile",8)==0)
502 helpfile=scan(buffer[i],&temp);
503 else if (strncasecmp(buffer[i],"LanguageMonitor",15)==0)
504 languagemonitor=scan(buffer[i],&temp);
505 else if (strncasecmp(buffer[i],"DefaultDataType",15)==0)
506 datatype=scan(buffer[i],&temp);
507 else if (strncasecmp(buffer[i],"VendorSetup",11)==0)
508 vendorsetup=scan(buffer[i],&temp);
509 i++;
513 if (languagemonitor) {
514 temp = strtok(languagemonitor,",");
515 if (*temp == '"') ++temp;
516 pstrcpy(languagemonitor,temp);
517 if ((temp = strchr(languagemonitor,'"'))!=NULL) *temp = '\0';
520 if (i) fprintf(stderr,"End of section found\n");
522 fprintf(stderr,"CopyFiles: %s\n",
523 copyfiles?copyfiles:"(null)");
524 fprintf(stderr,"Datasection: %s\n",
525 datasection?datasection:"(null)");
526 fprintf(stderr,"Datafile: %s\n",
527 datafile?datafile:"(null)");
528 fprintf(stderr,"Driverfile: %s\n",
529 driverfile?driverfile:"(null)");
530 fprintf(stderr,"Helpfile: %s\n",
531 helpfile?helpfile:"(null)");
532 fprintf(stderr,"LanguageMonitor: %s\n",
533 languagemonitor?languagemonitor:"(null)");
534 fprintf(stderr,"VendorSetup: %s\n",
535 vendorsetup?vendorsetup:"(null)");
536 if (copyfiles) scan_copyfiles(fichier,copyfiles);
539 int main(int argc, char *argv[])
541 char *short_desc;
542 FILE *inf_file;
544 fprintf( stderr, "This tool has been deprecated in favor of the new printer administration\n");
545 fprintf( stderr, "model included in Samba 2.2. Please see the HOWTO in docs/textdocs/printer_driver2.html\n");
546 fprintf( stderr, "for details.\n");
548 if (argc!=3)
550 usage(argv[0]);
551 return(-1);
554 inf_file=sys_fopen(argv[1],"r");
555 if (!inf_file)
557 fprintf(stderr,"Description file not found, bye\n");
558 return(-1);
561 lookup_strings(inf_file);
563 short_desc=find_desc(inf_file,argv[2]);
564 if (short_desc==NULL)
566 fprintf(stderr,"Printer not found\n");
567 return(-1);
569 else fprintf(stderr,"Found:%s\n",short_desc);
571 lookup_entry(inf_file,"DestinationDirs");
572 build_subdir();
574 if((files_to_copy=(char *)malloc(2048*sizeof(char))) == NULL) {
575 fprintf(stderr, "%s: malloc fail.\n", argv[0] );
576 exit(1);
578 *files_to_copy='\0';
579 scan_short_desc(inf_file,short_desc);
580 fprintf(stdout,"%s:%s:%s:",
581 argv[2],driverfile,datafile);
582 fprintf(stdout,"%s:",
583 helpfile?helpfile:"");
584 fprintf(stdout,"%s:",
585 languagemonitor?languagemonitor:"");
586 fprintf(stdout,"%s:",datatype);
587 fprintf(stdout,"%s\n",files_to_copy);
588 return 0;