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