Home | History | Annotate | Download | only in mp
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright (c) 2000 by Sun Microsystems, Inc.
     23  * All rights reserved.
     24  */
     25 /*  @(#)main.c 3.9 99/09/16
     26  *
     27  *  Takes a mail file, a news article or an ordinary file
     28  *  and pretty prints it on a Postscript printer.
     29  *
     30  *  Copyright (c) Steve Holden and Rich Burridge.
     31  *                All rights reserved.
     32  *
     33  *  Permission is given to distribute these sources, as long as the
     34  *  copyright messages are not removed, and no monies are exchanged.
     35  *
     36  *  No responsibility is taken for any errors inherent either
     37  *  to the comments or the code of this program, but if reported
     38  *  to me then an attempt will be made to fix them.
     39  */
     40 
     41 #include "mp.h"
     42 #include "general_header.h"
     43 #include <stdlib.h>
     44 #include <sys/param.h>
     45 #include <nl_types.h>
     46 #include <locale.h>
     47 #include <sys/stat.h>
     48 
     49 extern void pcf_tt_put_postscript_prologue(void);
     50 Bool set_current_locale(void);
     51 static void put_environment_var ( char *, char *);
     52 static void PS_out();
     53 
     54 /* Command line option flags */
     55 
     56 bool use_mp_conf  = FALSE ;   /* Use mp.conf even if prolog.ps file is present*/
     57 bool article  = FALSE ;       /* Set for news in "Article from " format. */
     58 bool content  = FALSE ;       /* Set if Content-Length: has message length. */
     59 bool digest   = FALSE ;       /* Are we are printing a mail digest (-d) */
     60 bool elm_if   = FALSE ;       /* ELM mail frontend intermediate file format */
     61 bool folder   = FALSE ;       /* Set if we are printing a mail folder. */
     62 bool nodecor   = FALSE ;       /* Set if we are printing without decorations */
     63 bool landscape = FALSE ;      /* Set if we are printing in landscape mode. */
     64 bool print_orig = FALSE ;     /* Print From rather than To in mail header. */
     65 bool print_ps = FALSE ;        /* Print PostScript files if set. */
     66 bool text_doc = FALSE ;       /* Printing normal text (-o) */
     67 bool multi_print_var = FALSE ;    /* Whether to print using the configuration mech or as print server client*/
     68 
     69 /* Header definitions. */
     70 
     71 char *POSTSCRIPT_MAGIC = "%!" ;            /* First line of PS file. */
     72 
     73 /* Bug # 4010691 */
     74 char *X_UNIX_FROM	= "X-Unix-From:" ; /* mail seperator in a folder */
     75 
     76 char *FROMHDR       = "From:" ;
     77 char *FROM_HDR      = "From " ;            /* UNIX From header */
     78 char *APP_FROMHDR   = "Apparently_from:" ;
     79 char *TOHDR         = "To:" ;
     80 char *APP_TOHDR     = "Apparently_to:" ;
     81 char *CCHDR         = "Cc:" ;
     82 char *SUBJECTHDR    = "Subject:" ;
     83 char *DATEHDR       = "Date:" ;
     84 char *NEWSGROUPSHDR = "Newsgroups:" ;
     85 char *NEWSGROUPHDR  = "Newsgroup:" ;
     86 char *REPLYHDR      = "Reply_to:" ;
     87 char *CONTENT_LEN   = "Content-Length:" ;
     88 
     89 /* Header lines. */
     90 
     91 char *from            = NULL ;    /* From: */
     92 char *from_           = NULL ;    /* From_ (UNIX from) */
     93 char *apparently_from = NULL ;    /* Apparently_from: */
     94 char *to[MAXCONT+1] ;             /* To: (can have multiple lines) */
     95 char *apparently_to   = NULL ;    /* Apparently_to: */
     96 char *cc[MAXCONT+1] ;             /* Cc: (can have multiple lines) */
     97 char *subject         = NULL ;      /* Subject: (can be set from command line) */
     98 char *gsubject        = NULL ;    /* Global subject set from command line. */
     99 char *date            = NULL ;    /* Date: */
    100 char *newsgroups      = NULL ;    /* Newsgroups: (news articles only) */
    101 char *reply_to        = NULL ;    /* Reply-to: */
    102 char *content_len     = NULL ;    /* Content-Length: */
    103 
    104 /* Strings used in page processing. */
    105 
    106 char *curfname = NULL;       /* Current file being printed. */
    107 char *message_for = "" ;          /* "[Mail,News,Listing] for " line */
    108 char *nameptr ;                   /* Used to getenv the NAME variable. */
    109 char *optarg = NULL;                    /* Optional command line argument. */
    110 char *owner       = NULL ;        /* Name of owner (usually equal to 'to') */
    111 char *progname    = NULL ;        /* Name of this program. */
    112 char *prologue    = PROLOGUE ;    /* Name of PostScript prologue file. */
    113 char *proname = NULL;        /* Full pathname of the prologue file. */
    114 char *whoami      = NULL ;        /* Login name of user. */
    115 char *prolog_locale = NULL ;      /* Locale of prolog file */
    116 char *target_printer = NULL ;	  /* Name of target printer */
    117 char *mpconf_path = NULL ;	  /* User specified config. path */
    118 int octal = 0 ;                   /* Does "nextline" contain octal numbers */
    119 int dup_stdout_des ;		  /* duplicate stdout descriptor */
    120 
    121 /* newly defined globals */
    122 nl_catd  cat_fd = NULL;
    123 int current_pt_sz = NORMAL_PT_SZ;
    124 
    125 /* Other globals. */
    126 
    127 document_type doc_type = DO_MAIL ;  /* Printing type - default mail */
    128 paper_type paper_size = US ;        /* Paper size - default US */
    129 
    130 #ifdef GECOSFIELDS
    131 int namefields = GECOSFIELDS ;  /* New no. of "words" from passwd gecos. */
    132 #else
    133 int namefields = NAMEFIELDS ;   /* Not supplied; use default. */
    134 #endif /*GECOSFIELDS*/
    135 
    136 #ifdef GECOSLENGTH
    137 int namelength = GECOSLENGTH ;  /* New max. no. of chars. from passwd gecos. */
    138 #else
    139 int namelength = NAMELENGTH ;   /* Not supplied; use default. */
    140 #endif /*GECOSLENGTH*/
    141 
    142 int clen = 0 ;              /* Current line length (including newline). */
    143 int colct = 0;              /* Column count on current page. */
    144 int cmdfiles = 0 ;          /* Set if file to print given on command line. */
    145 int linect = 0 ;            /* Line count on current page. */
    146 int llen = LINELENGTH ;     /* Number of characters per line. */
    147 int mlen = 0 ;              /* Number of characters in message (-C option). */
    148 int numcols = 1 ;           /* Number of columns per page */
    149 int optind ;                /* Optional command line argument indicator. */
    150 int pageno = 1 ;            /* Page number within message. */
    151 int plen = PAGELENGTH ;     /* Number of lines per page. */
    152 int tpn    = 0 ;            /* Total number of pages printed. */
    153 
    154 /* Read-ahead variables. */
    155 
    156 char *nextline=NULL;  	       /* Read-ahead of the mail message, minus nl */
    157 
    158 bool end_of_file = FALSE ;     /* EOF indicator */
    159 bool end_of_line ;             /* Is a newline removed from this line */
    160 bool end_of_page = FALSE ;     /* end-of-page indicator - ^L on input */
    161 bool print_spool = FALSE ; 	/* Spool output in xpr client mode */
    162 
    163 FILE *fp ;                     /* File pointer for current file. */
    164 static int printed_once=0;
    165 
    166 int
    167 main(argc, argv)
    168 int argc ;
    169 char **argv ;
    170 {
    171   FILE **prolog_fp;
    172 
    173   to[0] = cc[0] = NULL ;
    174 
    175   progname = argv[0] ;        /* Save this program name. */
    176 
    177   /* For setting the path of tne message catalog file */
    178 
    179   get_def_style_file();
    180 
    181   get_options(argc, argv) ;   /* Read and process command line options. */
    182 
    183   (void)setlocale(LC_ALL, "");
    184 
    185   put_environment_var(NLS_PATH_ENVIRON,NLS_PATH_STRING);
    186 
    187   /* Opening the catalog file handle */
    188 
    189   cat_fd = catopen(MP_MSG_FILE, NL_CAT_LOCALE);
    190 
    191   (void) set_current_locale();
    192 
    193   /* Select suitable page format files for xprt client/ps printing */
    194   replace_str(proname,"%s",target_printer?"xpr":"ps");
    195   target_printer?multi_print_var=TRUE:NULL;
    196 
    197   prolog_fp=(FILE **)calloc(sizeof(FILE *),1);
    198   *prolog_fp=(FILE *)calloc(sizeof(FILE),1);
    199 
    200   if(target_printer==NULL) {	/* Not xprt client */
    201   	postscript_onetime_routine(prolog_fp);
    202   } else {
    203 	dup_stdout_des = dup(1);	/* create a dupli.desc for stdout */
    204 	freopen("/dev/null","wb",stdout);
    205   	if(target_printer)
    206   		xpr_init();
    207   }
    208 
    209   if (argc - optind != 0) cmdfiles = 1 ;
    210   if (!cmdfiles)
    211     {
    212       fp = stdin ;                 /* Get input from standard input. */
    213       curfname=(char *)strdup("stdin");
    214       STRCPY(curfname, "stdin") ;
    215       if(!target_printer) {
    216 	      if(!test_postscript(fp)) {
    217 		      postscript_out(prolog_fp) ;
    218 		      readline();
    219 		      printfile() ;   /* Pretty print *just* standard input. */
    220 		     show_trailer() ; /* Send trailer file to output. */
    221 	     }
    222      } else {
    223 	printfile() ;
    224      }
    225     }
    226   else
    227     for (; optind < argc; ++optind)
    228       {
    229         if(argv[optind]!=NULL) {
    230 		unsigned int tmp_len=strlen(argv[optind]);
    231 		curfname=(char*)realloc(curfname, tmp_len+1);
    232 		if(!curfname)
    233 			malloc_err_disp_exit(__LINE__, __FILE__);
    234         	STRCPY(curfname, argv[optind]) ;    /* Current file to print. */
    235 	} else {
    236 		continue;			/* File is empty ! */
    237 	}
    238 	if ((fp = fopen(curfname, "r"))==NULL) {
    239 		FPRINTF(stderr , catgets(cat_fd, ERR_SET, 1, \
    240 		"%s: cannot open file %s \n"), progname, curfname) ;
    241 		continue;
    242 	}
    243         colct = 0 ;
    244         pageno = 1 ;       /* Initialise current page number. */
    245 	tpn = 0;
    246         end_of_file = 0 ;  /* Reset in case there's another file to print. */
    247 	if (!target_printer) {
    248 		if(*prolog_fp)
    249 			fseek(*prolog_fp, 0L, SEEK_SET);
    250 		if(!test_postscript(fp)) {
    251 			postscript_out(prolog_fp) ;
    252 			readline();
    253 			printfile() ;      /* Pretty print current file. */
    254 			show_trailer() ;   /* Send trailer file to output. */
    255 		}
    256 	} else {
    257 		printfile() ;
    258 	}
    259      }
    260   if(*prolog_fp)
    261   	FCLOSE(*prolog_fp);
    262   if(printed_once && target_printer )
    263 	xpr_end();
    264   exit(0) ;
    265 /*NOTREACHED*/
    266 }
    267 
    268 
    269 int
    270 printfile()    /* Create PostScript to pretty print the current file. */
    271 {
    272   int blankslate ;    /* Nothing set up for printing. */
    273   bool eop ;          /* Set if ^L (form-feed) found. */
    274 
    275   if (target_printer)
    276 	readline();
    277 
    278   if (end_of_file)
    279     {
    280 	FPRINTF(stderr , catgets(cat_fd, ERR_SET, 2, \
    281 		"%s: empty input file %s, nothing printed\n"), progname, curfname) ;
    282       return(1) ;
    283     }
    284 
    285   printed_once=1;
    286   if (!text_doc)
    287     parse_headers(FALSE) ;    /* Parse headers of mail or news article */
    288   init_setup() ;              /* Set values for remaining globals. */
    289 
    290   startfile();
    291   startpage() ;               /* Output initial definitions. */
    292   blankslate = 0 ;
    293   eop        = FALSE ;
    294 
    295 /* Print the document */
    296 
    297   if (doc_type != DO_TEXT)
    298     {
    299       show_headers(FALSE) ;
    300 #ifdef WANTED
    301       FPUTS("sf ", stdout) ;
    302 #endif /*WANTED*/
    303     }
    304   while (!end_of_file)
    305     {
    306       if (blankslate)
    307         {
    308           startfile() ;
    309           startpage() ;               /* Output initial definitions. */
    310           blankslate = 0 ;
    311         }
    312 
    313       if (content && folder && mlen <= 0)
    314         {
    315 
    316 /*  If the count has gone negative, then the Content-Length is wrong, so go
    317  *  back to looking for "\nFrom".
    318  */
    319 
    320           if (mlen < 0) content = FALSE ;
    321           else if ((hdr_equal(FROM_HDR) || hdr_equal(FROMHDR)) &&
    322                     isupper(nextline[0]))
    323             {
    324               eop    = FALSE ;
    325               linect = plen ;
    326               reset_headers() ;
    327               parse_headers(FALSE) ;
    328               show_headers(FALSE) ;
    329             }
    330           else content = FALSE ;
    331         }
    332 
    333 		/* bug#4010691 */
    334       if (!content && folder && hdr_equal(X_UNIX_FROM)
    335           /* (!elm_if && hdr_equal(FROM_HDR) ||
    336             elm_if && hdr_equal(FROMHDR)) */ && isupper(nextline[0]))
    337         {
    338           eop    = FALSE ;
    339           linect = plen ;
    340           reset_headers() ;
    341           parse_headers(FALSE) ;
    342           show_headers(FALSE) ;
    343         }
    344       if (digest &&
    345          (hdr_equal(FROMHDR) || hdr_equal(DATEHDR) || hdr_equal(SUBJECTHDR)) &&
    346           isupper(nextline[0]))
    347         {
    348           linect = plen ;
    349           parse_headers(TRUE) ;
    350           show_headers(TRUE) ;
    351         }
    352 
    353       if (print_ps && hdr_equal(POSTSCRIPT_MAGIC))
    354         {
    355           if (numcols) endcol() ;
    356           endpage() ;
    357           endfile() ;
    358           process_postscript() ;
    359           blankslate = 1 ;
    360         }
    361       else if (folder && end_of_page)
    362 	{
    363 	/*  Bug # 4010691 */
    364 	/* This line causes a blank page to print inbetween mails */
    365 	/*
    366 	eop = TRUE ;
    367 	*/
    368 	}
    369       else
    370         {
    371           if (eop == TRUE) end_of_page = TRUE ;
    372           textshow(nextline) ;
    373           eop = FALSE ;
    374         }
    375 
    376       if (content) mlen -= clen ;
    377       readline() ;
    378 
    379     }
    380 
    381   if(target_printer && end_of_file)
    382 	xpr_print(NULL, 0, FEND);
    383   if (!blankslate)
    384     {
    385       if (numcols) endcol() ;
    386       endpage() ;
    387       endfile() ;
    388     }
    389 
    390   FCLOSE(fp) ;
    391   return(1);
    392 }
    393 static void
    394 PS_out() {
    395   int firstline = 1 ;   /* To allow a newline after the first line. */
    396   FILE *fpprt = fdopen(dup_stdout_des, "w");
    397   while (!hdr_equal(FROMHDR)    && !hdr_equal(DATEHDR) &&
    398          !hdr_equal(SUBJECTHDR) && !end_of_file)
    399     {
    400       fprintf(fpprt,"%s", nextline) ;
    401       if (firstline) fprintf(fpprt,"\n");
    402       firstline = 0 ;
    403       if (fgets(nextline, MAXLINE, fp) == NULL) end_of_file = TRUE ;
    404     }
    405     fflush(fpprt);
    406     fclose(fpprt);
    407 }
    408 
    409 
    410 int
    411 process_postscript()
    412 {
    413   int firstline = 1 ;   /* To allow a newline after the first line. */
    414   if(target_printer) {
    415 	xpr_print(NULL, 0, FEND);
    416   	xpr_end();
    417 	PS_out();
    418 	return(0);
    419   }
    420   startpage() ;
    421   while (!hdr_equal(FROMHDR)    && !hdr_equal(DATEHDR) &&
    422          !hdr_equal(SUBJECTHDR) && !end_of_file)
    423     {
    424       PRINTF("%s", nextline) ;
    425       if (firstline) FPUTS("\n", stdout) ;
    426       firstline = 0 ;
    427       if (fgets(nextline, MAXLINE, fp) == NULL) end_of_file = TRUE ;
    428     }
    429   endpage() ;
    430 }
    431 
    432 
    433 int
    434 show_trailer()
    435 {
    436   FPUTS("%%Trailer\n", stdout) ;
    437   PRINTF("%%%%Pages: %1d\n", tpn) ;
    438 }
    439 
    440 static void
    441 put_environment_var ( char *env_var_name , char *env_var_value )
    442 {
    443 	char *after_environ_array;
    444      	char before_environ_array[MAX_ENV_STRING];
    445 	char *tempString;
    446 
    447 	tempString = (char *)getenv(env_var_name);
    448 	/*
    449 	 * this variable has to be malloc'ed as putenv won't
    450 	 * work good with auto vars.
    451 	 */
    452 	after_environ_array = (char *)malloc(MAX_ENV_STRING);
    453 	if ( after_environ_array == NULL )
    454 	{
    455 		fprintf(stderr, catgets( cat_fd, ERR_SET , 26,
    456 			"%s: Malloc failure; line %d, file %s\n"),progname,
    457 			__LINE__, __FILE__ );
    458 		exit(1);
    459 	}
    460 
    461 	if (!tempString)
    462      	{
    463 		sprintf(after_environ_array,"%s%s%s",
    464 			env_var_name,
    465 			"=",
    466 			env_var_value
    467 			);
    468 	} else
    469 	{
    470 		 sprintf(before_environ_array,"%s%s%s",
    471 			env_var_name ,
    472 			"=",
    473 			tempString
    474 			);
    475 		sprintf(after_environ_array,"%s%s%s%s%s",
    476 			env_var_name ,
    477 			"=",
    478 			tempString,
    479 			":",
    480 			env_var_value
    481 			);
    482 	}
    483 	putenv(after_environ_array);
    484 	/*
    485 	free(after_environ_array);
    486 	*/
    487 
    488 }
    489 
    490 Bool
    491 set_current_locale(void) {
    492 
    493   char *tmp = NULL;
    494   char *locale = NULL;
    495   Bool ret=FALSE;
    496 
    497   if ( prolog_locale != NULL && strcmp(prolog_locale,"") ) {     /* command line arg */
    498 	if ( (locale = setlocale(LC_ALL,prolog_locale)) != NULL)
    499 		ret=TRUE;
    500   } else if ( (tmp = (char *)getenv("MP_LANG")) && strcmp(tmp,"") ) {    /* environment var */
    501 	if ( (locale = setlocale(LC_ALL,tmp)) != NULL )
    502 		ret=TRUE;
    503   } else if ( (tmp = (char *)getenv("LANG")) != NULL && strcmp(tmp,"") ) {    /* environment var */
    504 	if ( (locale = setlocale(LC_ALL,tmp)) != NULL )
    505 		ret=TRUE;
    506   } else if ( (locale = setlocale(LC_ALL, (char *)NULL)) != NULL ) {
    507 		ret=TRUE;
    508   }
    509   /* this is a fix for bug#4311552, to make decimal point to appear thus, not
    510   as a semicolon in all the solaris locales */
    511 
    512   (void)setlocale(LC_NUMERIC, "C");
    513 
    514   return ret;
    515 }
    516 
    517 int
    518 test_hdrequal(val, lline)
    519 char val[MAXLINE];
    520 char lline[MAXLINE];
    521 {
    522 
    523   register char *nptr = lline ;
    524   register char *wptr = val ;
    525   register int n, w ;
    526 
    527   do
    528     {
    529       n = *nptr++ ;
    530       w = *wptr++ ;
    531       if (isupper(n)) n = tolower(n) ;
    532       if (isupper(w)) w = tolower(w) ;
    533       if (n != w && w != '\0') return(0) ;
    534     }
    535   while (n != '\0' && w != '\0') ;
    536   return(1) ;
    537 }
    538 
    539 int
    540 test_postscript(fp)
    541 FILE *fp;
    542 {
    543 char localline[MAXLINE];
    544 int c;
    545 
    546 	if ((c = getc(fp)) == EOF ) { end_of_file = TRUE ; }
    547 	else UNGETC(c, fp) ;
    548 	if (end_of_file) {
    549 		FPRINTF(stderr , catgets(cat_fd, ERR_SET, 2, \
    550 			"%s: empty input file %s, nothing printed\n"), progname, curfname) ;
    551 		return(1);
    552 	} else {
    553 		localline[0]=getc(fp);
    554 		localline[1]=getc(fp);
    555 		localline[2]='\n';
    556 		UNGETC(localline[1], fp);
    557 		UNGETC(localline[0], fp);
    558 
    559 #if 0
    560 		memset(localline, 0, MAXLINE);
    561   		readline() ;
    562 		strncpy(localline, nextline, clen);
    563 		localline[clen-1]='\n';
    564 		/*
    565 		fgets(localline, MAXLINE, fp);
    566 		*/
    567 #endif
    568 		if(!text_doc && test_hdrequal(POSTSCRIPT_MAGIC, localline)) {
    569 			while (!end_of_file) {
    570 				if (fgets(localline, MAXLINE, fp) == NULL ) end_of_file = TRUE ;
    571 				else PRINTF("%s", localline) ;
    572 			}
    573 		end_of_file = FALSE;
    574 		return 1;
    575 		}
    576 	return 0;
    577 	}
    578 }
    579 
    580 int
    581 postscript_onetime_routine(prolog_fp)
    582   FILE **prolog_fp;
    583 {
    584   char *i18n_prologfile0=NULL;
    585   char *i18n_prologfile0_tmp=NULL;
    586   char *i18n_prologfile=NULL;
    587   char *i18n_prologfile_tmp=NULL;
    588   char *confpath=NULL;
    589   char *confpath_tmp=NULL;
    590   char *tmp = NULL;
    591   char *t = NULL;
    592   char *locale = NULL;
    593   int setuplocale = 0;
    594 
    595   unsigned int i1=0, i2=0;
    596 
    597   i1=strlen(PROLOG_STR);
    598   i2=strlen(PROLOG_STR_OWN);
    599 
    600 
    601 /*  Try to get location of the mp prologue file from an environment variable.
    602  *  If it's not found, then use the default value.
    603  */
    604 
    605   if (prolog_locale && (strcmp(prolog_locale,"C") == 0)){
    606       *prolog_fp = NULL;
    607       setuplocale = 0;
    608   /* Figure out which locale document is in */
    609   } else if ( prolog_locale != NULL && strcmp(prolog_locale,"") && strcmp(prolog_locale,"C")) {     /* command line arg */
    610       tmp = prolog_locale;
    611       setuplocale = 1;
    612   } else if (((tmp = (char *)getenv("MP_LANG")) != NULL || (tmp = (char *)getenv("LANG")) != NULL) && strcmp(tmp,"") && strcmp(tmp,"C")) {    /* environment var */
    613       setuplocale = 1;
    614   } else { /* query locale */
    615       if ( (locale = setlocale(LC_ALL, (char *)NULL)) != NULL ) {
    616 	  if ( strcmp(locale, "C") == 0 ) { /* in C locale */
    617 	      *prolog_fp = NULL;
    618               setuplocale = 0;
    619 	  } else {
    620 		tmp=strtok(locale,"/");
    621 	      	setuplocale = 1;
    622 	  }
    623       }
    624   }
    625 
    626   if(setuplocale) {
    627 	  char *pl=NULL;
    628 	  unsigned int st=strlen(tmp)+1;
    629 	  i1+=st+20;
    630 	  i2+=st+20;
    631 	  pl = (char *)calloc(st+1, 1);
    632 	  if(!pl)
    633 		malloc_err_disp_exit(__LINE__, __FILE__);
    634 	  strcpy(pl,tmp);
    635   	  i18n_prologfile = (char *)calloc(i1, 1);
    636 	  if(!i18n_prologfile)
    637 		malloc_err_disp_exit(__LINE__, __FILE__);
    638   	  i18n_prologfile_tmp = (char *)calloc(i1, 1);
    639 	  if(!i18n_prologfile_tmp)
    640 		malloc_err_disp_exit(__LINE__, __FILE__);
    641   	  i18n_prologfile0 = (char *)calloc(i2, 1);
    642 	  if(!i18n_prologfile0)
    643 		malloc_err_disp_exit(__LINE__, __FILE__);
    644   	  i18n_prologfile0_tmp = (char *)calloc(i2, 1);
    645 	  if(!i18n_prologfile0_tmp)
    646 		malloc_err_disp_exit(__LINE__, __FILE__);
    647 	  confpath = (char *)calloc(i1, 1);
    648 	  if(!confpath)
    649 		malloc_err_disp_exit(__LINE__, __FILE__);
    650 	  confpath_tmp = (char *)calloc(i1, 1);
    651 	  if(!confpath_tmp)
    652 		malloc_err_disp_exit(__LINE__, __FILE__);
    653 	  SPRINTF(i18n_prologfile0, PROLOG_STR_OWN, tmp);
    654 	  SPRINTF(i18n_prologfile, PROLOG_STR, tmp);
    655 	  if ((t=(char *)strchr(pl,'@')) && (*t=NULL)) ;
    656 	  SPRINTF(i18n_prologfile_tmp, PROLOG_STR, pl);
    657 	  SPRINTF(i18n_prologfile0_tmp, PROLOG_STR_OWN, pl);
    658 	  free(pl);
    659   }
    660 
    661   if (mpconf_path) {
    662 	struct stat st;
    663 	if (stat(mpconf_path,&st) == -1) {
    664 		fprintf(stderr, catgets(cat_fd, ERR_SET,1, \
    665 			"%s: Cannot open %s\n"), progname, mpconf_path);
    666 		exit(-1);
    667 	}
    668   }
    669 
    670   if ( setuplocale ) {
    671 	  if(mpconf_path) {
    672 		strcpy(confpath, mpconf_path);
    673 	  } else {
    674   	  	SPRINTF(confpath, "%s/mp.conf", i18n_prologfile);
    675   	  	SPRINTF(confpath_tmp, "%s/mp.conf", i18n_prologfile_tmp);
    676 	  }
    677 	  strcat(i18n_prologfile0, "/prolog.ps");
    678 	  strcat(i18n_prologfile, "/prolog.ps");
    679 	  strcat(i18n_prologfile_tmp, "/prolog.ps");
    680 	  strcat(i18n_prologfile0_tmp, "/prolog.ps");
    681 	  /* Check whether prolog.ps exist */
    682 	  /* This order of checking is really important */
    683 	  if (((*prolog_fp = fopen(i18n_prologfile0, "r")) == NULL) &&
    684 	      	((*prolog_fp = fopen(i18n_prologfile0_tmp, "r")) == NULL) &&
    685 	      	((*prolog_fp = fopen(i18n_prologfile, "r")) == NULL) &&
    686 	      	((*prolog_fp = fopen(i18n_prologfile_tmp, "r")) == NULL) ||
    687 		use_mp_conf ) {
    688 		if (config_scan(confpath) ||
    689 			config_scan(confpath_tmp)) {
    690 			multi_print_var = TRUE;
    691 			*prolog_fp = NULL;
    692 		}
    693 		/* prolog.ps does not exist - such as in European locales */
    694 		setuplocale = 0;
    695 	  } else {
    696 		setuplocale = 1;
    697 	  }
    698   } else {
    699 	if(mpconf_path) {
    700 		if(!confpath) {
    701 			confpath=(char*)calloc(strlen(mpconf_path)+1,1);
    702 	  		if(!confpath)
    703 				malloc_err_disp_exit(__LINE__, __FILE__);
    704 		}
    705 		strcpy(confpath, mpconf_path);
    706 	}
    707 
    708 	if (confpath && config_scan(confpath)) multi_print_var = TRUE;
    709 	setuplocale = 0;
    710  }
    711 
    712   if(i18n_prologfile)
    713 	free(i18n_prologfile);
    714   if(i18n_prologfile_tmp)
    715 	free(i18n_prologfile_tmp);
    716   if(i18n_prologfile0)
    717 	free(i18n_prologfile0);
    718   if(i18n_prologfile0_tmp)
    719 	free(i18n_prologfile0_tmp);
    720   if(confpath)
    721 	free(confpath);
    722   if(confpath_tmp)
    723 	free(confpath_tmp);
    724 
    725 	return setuplocale;
    726 }
    727 void output_prolog_ps(prolog_fp)
    728 FILE **prolog_fp;
    729 {
    730     char buf[MAXLINE];
    731     while ( fgets(buf, MAXLINE, *prolog_fp) != NULL ) {
    732 	FPUTS(buf, stdout);
    733     }
    734 }
    735 int postscript_out(prolog_fp)
    736 FILE **prolog_fp;
    737 {
    738       if(*prolog_fp!=(FILE *)NULL) {
    739 	output_prolog_ps(prolog_fp);
    740 	FPUTS("/localeprolog 1 def\n\n", stdout);
    741       } else {
    742 	FPUTS("%!PS-Adobe-1.0\n", stdout);
    743 	FPUTS("/localeprolog 0 def\n\n", stdout);
    744       }
    745 
    746       show_prologue(proname) ;    /* Send prologue file to output. */
    747       FPUTS("%%EndProlog\n", stdout) ;
    748       write_output("/CP /currentpoint\tload def\n");
    749       write_output("/M /moveto\tload def\n");
    750       write_output("/SH /show\tload def\n");
    751       return 0;
    752 }
    753 int  get_def_style_file()
    754 {
    755   unsigned int pron_size = 0;
    756   if ((prologue = (char *)getenv("MP_PROLOGUE")) == NULL)
    757     {
    758           char buf[MAXPATHLEN] ;
    759 
    760           SPRINTF(buf, DEF_PROLOG_DIR) ;
    761           prologue = (char *) strdup(buf) ;
    762     }
    763   pron_size=strlen(prologue)+21;
    764   proname=(char*)realloc(proname, pron_size);
    765   if(!proname)
    766 	  malloc_err_disp_exit(__LINE__, __FILE__);
    767   SPRINTF(proname, "%s/mp.pro.%%s", prologue) ;
    768   return 0;
    769 }
    770