Removed version number from file header.
[ira/wip.git] / source3 / utils / make_printerdef.c
1  /*
2    Unix SMB/CIFS implementation.
3    Create printer definition files.
4
5    Copyright (C) Jean-Francois.Micouleau@utc.fr, 10/26/97 - 1998
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 /*
25 #define DEBUGIT
26 */
27
28 char *files_to_copy;
29 char *driverfile, *datafile, *helpfile, *languagemonitor, *datatype, *vendorsetup;
30 char buffer[50][sizeof(pstring)];
31 char sbuffer[50][sizeof(pstring)];
32 char sub_dir[50][2][sizeof(pstring)];
33
34 static void usage(char *name)
35 {
36  fprintf(stderr,"%s: printer.def \"Printer Name\"\n", name);
37 }
38
39 static char *myfgets(char *s, int n, FILE *stream)
40 {
41   char *LString1;
42   char *LString2;
43   char *temp;
44   pstring String;
45   pstring NewString;
46   int i;
47
48   fgets(s,n,stream);
49   while ((LString1 = strchr_m(s,'%')) != NULL) {
50     if (!(LString2 = strchr_m(LString1+1,'%'))) break;
51     *LString2 = '\0';
52     pstrcpy(String,LString1+1);
53     i = 0;
54     while(*sbuffer[i]!='\0') {
55       if (strncmp(sbuffer[i],String,strlen(String))==0)
56       {
57         pstrcpy(String,sbuffer[i]);
58         if ((temp = strchr_m(String,'=')) != NULL) ++temp;
59         pstrcpy(String,temp);
60         break;
61       }
62       i++;      
63     }
64     *LString1 = '\0';
65     pstrcpy(NewString,s);
66     pstrcat(NewString,String);
67     pstrcat(NewString,LString2+1);
68     pstrcpy(s, NewString);
69   }
70   return(s);
71 }
72
73 /*
74    This function split a line in two parts
75    on both side of the equal sign
76    "entry=value"
77 */
78 static char *scan(char *chaine,char **entry)
79 {
80   char *value;
81   char *temp;
82   int i=0;
83  
84   *entry=(char *)malloc(sizeof(pstring));
85   value=(char *)malloc(sizeof(pstring));
86
87   if(*entry == NULL || value == NULL) {
88     fprintf(stderr,"scan: malloc fail !\n");
89     exit(1);
90   }
91
92   pstrcpy(*entry,chaine);
93   temp=chaine;
94   while( temp[i]!='=' && temp[i]!='\0') {
95         i++;
96   }
97   (*entry)[i]='\0'; 
98   if (temp[i]!='\0') {
99         i++;
100   }
101   while( temp[i]==' ' && temp[i]!='\0') {
102         i++;
103   }
104   pstrcpy(value,temp+i);      
105   return (value);
106 }
107
108 static void build_subdir(void)
109 {
110   int i=0;
111   int j=0;
112   char *entry;
113   char *data;
114  
115   while (*buffer[i]!='\0') { 
116     data=scan(buffer[i],&entry);
117 #ifdef DEBUGIT
118     fprintf(stderr,"\tentry=data %s:%s\n",entry,data);
119 #endif      
120     j = strlen(entry);
121     while (j) {
122       if (entry[j-1] != ' ') break;
123       j--;
124     }
125     entry[j] = '\0';
126
127     if (strncmp(data,"11",2)==0) {
128       pstrcpy(sub_dir[i][0],entry);
129       pstrcpy(sub_dir[i][1],"");
130     }
131     if (strncmp(data,"23",2)==0) {
132       pstrcpy(sub_dir[i][0],entry);
133       pstrcpy(sub_dir[i][1],"color\\");
134     }
135 #ifdef DEBUGIT
136     fprintf(stderr,"\tsubdir %s:%s\n",sub_dir[i][0],sub_dir[i][1]);
137 #endif      
138     i++;
139   }
140 }
141
142 /*
143    Lockup Strings entry in a file
144    Return all the lines between the entry and the next one or the end of file
145    An entry is something between braces.
146 */
147 static void lookup_strings(FILE *fichier)
148 {
149   int found=0,pointeur=0,i=0;
150   char *temp,*temp2;
151   
152   temp=(char *)malloc(sizeof(pstring));
153   temp2=(char *)malloc(sizeof(pstring));
154   
155   if(temp == NULL || temp2 == NULL) {
156           SAFE_FREE(temp);
157           SAFE_FREE(temp2);
158     fprintf(stderr,"lookup_strings: malloc fail !\n");
159     exit(1);
160   }
161
162   *sbuffer[0]='\0';
163   
164   pstrcpy(temp2,"[Strings]");
165   
166   rewind(fichier);
167 #ifdef DEBUGIT
168   fprintf(stderr,"\tLooking for Strings\n");
169 #endif
170   
171   while (!feof(fichier) && found==0) {
172         *temp='\0';
173         fgets(temp,255,fichier);
174         if (strncmp(temp,temp2,strlen(temp2))==0) found=1;
175   }
176
177
178   while (!feof(fichier) && found==1) {
179         *temp='\0';
180         fgets(temp,255,fichier);
181         if (*temp=='[') {
182                 found=2;
183                 *sbuffer[pointeur]='\0';
184         }
185         else {
186                 pstrcpy(sbuffer[pointeur],temp);
187                 i=strlen(sbuffer[pointeur])-1;
188                 while (sbuffer[pointeur][i]=='\r' || sbuffer[pointeur][i]=='\n')
189                         sbuffer[pointeur][i--]='\0';
190                 pointeur++;
191         }  
192   }
193
194   /* CCMRCF Mod, seg fault or worse if not found */
195   if (pointeur == 0) {
196      fprintf(stderr,"Printer not found\tNo [Strings] block in inf file\n");
197      exit(2);
198   }
199
200 #ifdef DEBUGIT
201   fprintf(stderr,"\t\tFound %d entries\n",pointeur-1);
202 #endif
203 }
204
205
206 /*
207    Lockup an entry in a file
208    Return all the lines between the entry and the next one or the end of file
209    An entry is something between braces.
210 */
211 static void lookup_entry(FILE *fichier,char *chaine)
212 {
213   int found=0,pointeur=0,i=0;
214   char *temp,*temp2;
215   
216   temp=(char *)malloc(sizeof(pstring));
217   temp2=(char *)malloc(sizeof(pstring));
218   
219   if(temp == NULL || temp2 == NULL) {
220           SAFE_FREE(temp);
221           SAFE_FREE(temp2);
222     fprintf(stderr,"lookup_entry: malloc fail !\n");
223     exit(1);
224   }
225
226   *buffer[0]='\0';
227   
228   pstrcpy(temp2,"[");
229   pstrcat(temp2,chaine);
230   pstrcat(temp2,"]");
231   
232   rewind(fichier);
233 #ifdef DEBUGIT
234   fprintf(stderr,"\tLooking for %s\n",chaine);
235 #endif
236   
237   while (!feof(fichier) && found==0) {
238         *temp='\0';
239         myfgets(temp,255,fichier);
240         if (strncmp(temp,temp2,strlen(temp2))==0) found=1;
241   }
242
243
244   while (!feof(fichier) && found==1) {
245         *temp='\0';
246         myfgets(temp,255,fichier);
247         if (*temp=='[') {
248                 found=2;
249                 *buffer[pointeur]='\0';
250         }
251         else {
252                 pstrcpy(buffer[pointeur],temp);
253                 i=strlen(buffer[pointeur])-1;
254                 while (buffer[pointeur][i]=='\r' || buffer[pointeur][i]=='\n')
255                         buffer[pointeur][i--]='\0';
256                 pointeur++;
257         }  
258   }
259 #ifdef DEBUGIT
260   fprintf(stderr,"\t\tFound %d entries\n",pointeur-1);
261 #endif
262 }
263
264 static char *find_desc(FILE *fichier,char *text)
265 {
266   char *chaine;
267   char *long_desc;
268   char *short_desc;
269   char *crap = NULL;
270   char *p;
271
272   int found=0;
273
274   chaine=(char *)malloc(sizeof(pstring));
275   long_desc=(char *)malloc(sizeof(pstring));
276   short_desc=(char *)malloc(sizeof(pstring));
277   if (!chaine || !long_desc || !short_desc) {
278           SAFE_FREE(chaine);
279           SAFE_FREE(long_desc);
280           SAFE_FREE(short_desc);
281     fprintf(stderr,"find_desc: Unable to malloc memory\n");
282     exit(1);
283   }
284
285   rewind(fichier);
286   while (!feof(fichier) && found==0)
287   {
288     myfgets(chaine,255,fichier);
289
290     long_desc=strtok(chaine,"=");
291     crap=strtok(NULL,",\r");
292
293     p=long_desc;
294     while(*p!='"' && *p!='\0')
295      p++;
296     if (*p=='"' && *(p+1)!='\0') p++;       
297     long_desc=p;
298
299     if (*p!='\0')
300     {
301       p++;
302       while(*p!='\"')
303        p++;
304       *p='\0';
305     }
306     if (!strcmp(text,long_desc)) 
307         found=1;
308   }
309   SAFE_FREE(chaine);
310   if (!found || !crap) return(NULL);
311   while(*crap==' ') crap++;
312   pstrcpy(short_desc,crap);
313   return(short_desc);
314 }
315
316 static void scan_copyfiles(FILE *fichier, char *chaine)
317 {
318   char *part;
319   char *mpart;
320   int i;
321   pstring direc;
322 #ifdef DEBUGIT
323   fprintf(stderr,"In scan_copyfiles Lookup up of %s\n",chaine);
324 #endif 
325   fprintf(stderr,"\nCopy the following files to your printer$ share location:\n");
326   part=strtok(chaine,",");
327   do {
328      /* If the entry start with a @ then it's a file to copy
329      else it's an entry refering to files to copy
330      the main difference is when it's an entry
331      you can have a directory to append before the file name
332     */
333     if (*part=='@') {
334       if (strlen(files_to_copy) != 0)
335         pstrcat(files_to_copy,",");
336       pstrcat(files_to_copy,&part[1]);
337       fprintf(stderr,"%s\n",&part[1]);
338     } else {
339       lookup_entry(fichier,part);
340       i=0;
341       pstrcpy(direc,"");
342       while (*sub_dir[i][0]!='\0') {
343 #ifdef DEBUGIT
344         fprintf(stderr,"\tsubdir %s:%s\n",sub_dir[i][0],sub_dir[i][1]);
345 #endif      
346         if (strcmp(sub_dir[i][0],part)==0)
347           pstrcpy(direc,sub_dir[i][1]);
348         i++;
349       } 
350       i=0;
351       while (*buffer[i]!='\0') {
352 /*
353  * HP inf files have strange entries that this attempts to address
354  * Entries in the Copy sections normally have only a single file name
355  * on each line. I have seen the following format in various HP inf files:
356  * 
357  * pscript.hlp =  pscript.hl_
358  * hpdcmon.dll,hpdcmon.dl_
359  * MSVCRT.DLL,MSVCRT.DL_,,32
360  * ctl3dv2.dll,ctl3dv2.dl_,ctl3dv2.tmp
361  *
362  * In the first 2 cases you want the first file name - in the last case
363  * you only want the last file name (at least that is what a Win95
364  * machine sent). In the third case you also want the first file name
365  * (detect by the last component being just a number ?).
366  * This may still be wrong but at least I get the same list
367  * of files as seen on a printer test page.
368  */
369         part = strchr_m(buffer[i],'=');
370         if (part) {
371           /*
372            * Case (1) eg. pscript.hlp =  pscript.hl_ - chop after the first name.
373            */
374
375           *part = '\0';
376
377           /*
378            * Now move back to the start and print that.
379            */
380
381           while (--part > buffer[i]) {
382             if ((*part == ' ') || (*part =='\t'))
383               *part = '\0';
384             else
385               break;
386           }
387         } else {
388           part = strchr_m(buffer[i],',');
389           if (part) {
390             /*
391              * Cases (2-4)
392              */
393
394             if ((mpart = strrchr_m(part+1,','))!=NULL) {
395               /*
396                * Second ',' - case 3 or 4.
397                * Check if the last part is just a number,
398                * if so we need the first part.
399                */
400
401               char *endptr = NULL;
402               BOOL isnumber = False;
403
404               mpart++;
405               (void)strtol(mpart, &endptr, 10);
406
407               isnumber = ((endptr > mpart) && isdigit(*mpart));
408               if(!isnumber)
409                 pstrcpy(buffer[i],mpart+1);
410               else
411                 *part = '\0';
412             } else {
413               *part = '\0';
414             }
415             while (--part > buffer[i])
416               if ((*part == ' ') || (*part =='\t')) *part = '\0';
417               else break;
418           }
419             }
420         if (*buffer[i] != ';') {
421           if (strlen(files_to_copy) != 0)
422             pstrcat(files_to_copy,",");
423           pstrcat(files_to_copy,direc);
424           pstrcat(files_to_copy,buffer[i]);
425           fprintf(stderr,"%s%s\n",direc,buffer[i]);
426         }
427         i++;
428       } /* end while */ 
429     }
430     part=strtok(NULL,",");
431     if (part) {
432       while( *part ==' ' && *part != '\0') {
433         part++;
434       }
435     }
436   } while (part!=NULL);
437   fprintf(stderr,"\n");
438 }
439
440
441 static void scan_short_desc(FILE *fichier, char *short_desc)
442 {
443   int i=0;
444   char *temp;
445   char *copyfiles=0,*datasection=0;
446  
447   helpfile=0;
448   languagemonitor=0;
449   vendorsetup=0;
450   datatype="RAW";
451   if((temp=(char *)malloc(sizeof(pstring))) == NULL) {
452     fprintf(stderr, "scan_short_desc: malloc fail !\n");
453     exit(1);
454   }
455   
456   driverfile=short_desc;
457   datafile=short_desc;
458
459   lookup_entry(fichier,short_desc);
460
461   while(*buffer[i]!='\0') {
462 #ifdef DEBUGIT
463     fprintf(stderr,"\tLookup up of %s\n",buffer[i]);
464 #endif
465     if (strncasecmp(buffer[i],"CopyFiles",9)==0) 
466         copyfiles=scan(buffer[i],&temp);
467     else if (strncasecmp(buffer[i],"DataSection",11)==0) 
468         datasection=scan(buffer[i],&temp);
469     else if (strncasecmp(buffer[i],"DataFile",8)==0) 
470         datafile=scan(buffer[i],&temp);
471     else if (strncasecmp(buffer[i],"DriverFile",10)==0) 
472         driverfile=scan(buffer[i],&temp);
473     else if (strncasecmp(buffer[i],"HelpFile",8)==0) 
474         helpfile=scan(buffer[i],&temp);
475     else if (strncasecmp(buffer[i],"LanguageMonitor",15)==0) 
476         languagemonitor=scan(buffer[i],&temp);
477     else if (strncasecmp(buffer[i],"DefaultDataType",15)==0) 
478         datatype=scan(buffer[i],&temp);
479     else if (strncasecmp(buffer[i],"VendorSetup",11)==0) 
480         vendorsetup=scan(buffer[i],&temp);
481     i++;        
482   }
483
484   if (datasection) {
485     lookup_entry(fichier,datasection);
486
487     i = 0;
488     while(*buffer[i]!='\0') {
489 #ifdef DEBUGIT
490       fprintf(stderr,"\tLookup up of %s\n",buffer[i]);
491 #endif
492       if (strncasecmp(buffer[i],"CopyFiles",9)==0) 
493           copyfiles=scan(buffer[i],&temp);
494       else if (strncasecmp(buffer[i],"DataSection",11)==0) 
495           datasection=scan(buffer[i],&temp);
496       else if (strncasecmp(buffer[i],"DataFile",8)==0) 
497           datafile=scan(buffer[i],&temp);
498       else if (strncasecmp(buffer[i],"DriverFile",10)==0) 
499           driverfile=scan(buffer[i],&temp);
500       else if (strncasecmp(buffer[i],"HelpFile",8)==0) 
501           helpfile=scan(buffer[i],&temp);
502       else if (strncasecmp(buffer[i],"LanguageMonitor",15)==0) 
503           languagemonitor=scan(buffer[i],&temp);
504       else if (strncasecmp(buffer[i],"DefaultDataType",15)==0) 
505           datatype=scan(buffer[i],&temp);
506       else if (strncasecmp(buffer[i],"VendorSetup",11)==0) 
507           vendorsetup=scan(buffer[i],&temp);
508       i++;      
509     }
510   }
511
512   if (languagemonitor) {
513         temp = strtok(languagemonitor,",");
514         if (*temp == '"') ++temp;
515         pstrcpy(languagemonitor,temp);
516         if ((temp = strchr_m(languagemonitor,'"'))!=NULL) *temp = '\0';
517   }
518
519   if (i) fprintf(stderr,"End of section found\n");
520  
521   fprintf(stderr,"CopyFiles: %s\n",
522         copyfiles?copyfiles:"(null)");
523   fprintf(stderr,"Datasection: %s\n",
524         datasection?datasection:"(null)");
525   fprintf(stderr,"Datafile: %s\n",
526         datafile?datafile:"(null)");
527   fprintf(stderr,"Driverfile: %s\n",
528         driverfile?driverfile:"(null)");
529   fprintf(stderr,"Helpfile: %s\n",
530         helpfile?helpfile:"(null)");
531   fprintf(stderr,"LanguageMonitor: %s\n",
532         languagemonitor?languagemonitor:"(null)");
533   fprintf(stderr,"VendorSetup: %s\n",
534         vendorsetup?vendorsetup:"(null)");
535   if (copyfiles) scan_copyfiles(fichier,copyfiles);
536 }
537
538 int main(int argc, char *argv[])
539 {
540   char *short_desc;
541   FILE *inf_file;
542
543   if (argc!=3)
544   {
545     usage(argv[0]);
546     return(-1);
547   }
548
549   inf_file=sys_fopen(argv[1],"r");  
550   if (!inf_file)
551   {
552     fprintf(stderr,"Description file not found, bye\n");
553     return(-1);
554   }
555
556   lookup_strings(inf_file);
557
558   short_desc=find_desc(inf_file,argv[2]);
559   if (short_desc==NULL)
560   {
561     fprintf(stderr,"Printer not found\n");
562     return(-1);
563   }
564   else fprintf(stderr,"Found:%s\n",short_desc);
565
566   lookup_entry(inf_file,"DestinationDirs");
567   build_subdir();
568
569   if((files_to_copy=(char *)malloc(2048*sizeof(char))) == NULL) {
570     fprintf(stderr, "%s: malloc fail.\n", argv[0] );
571     exit(1);
572   }
573   *files_to_copy='\0';
574   scan_short_desc(inf_file,short_desc);
575   fprintf(stdout,"%s:%s:%s:",
576     argv[2],driverfile,datafile);
577   fprintf(stdout,"%s:",
578     helpfile?helpfile:"");
579   fprintf(stdout,"%s:",
580     languagemonitor?languagemonitor:"");
581   fprintf(stdout,"%s:",datatype);
582   fprintf(stdout,"%s\n",files_to_copy);
583   return 0;
584 }
585