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