1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1995 by Sun Microsystems, Inc. 24*7c478bd9Sstevel@tonic-gate */ 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate #include <stdio.h> 29*7c478bd9Sstevel@tonic-gate #include <limits.h> 30*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 31*7c478bd9Sstevel@tonic-gate #include <string.h> 32*7c478bd9Sstevel@tonic-gate #include <stdarg.h> 33*7c478bd9Sstevel@tonic-gate #include <libintl.h> 34*7c478bd9Sstevel@tonic-gate #include <locale.h> 35*7c478bd9Sstevel@tonic-gate #include <libgen.h> 36*7c478bd9Sstevel@tonic-gate #include <ctype.h> 37*7c478bd9Sstevel@tonic-gate #include <unistd.h> 38*7c478bd9Sstevel@tonic-gate #include <signal.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate #include "genmsg.h" 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #define SET_TOKEN "$set" 45*7c478bd9Sstevel@tonic-gate #define DELSET_TOKEN "$delset" 46*7c478bd9Sstevel@tonic-gate #define QUOTE_TOKEN "$quote" 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate #define SkipSpace(s) while (*(s) == ' ' || *(s) == '\t') s++ 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate extern char *program; /* from main.c */ 51*7c478bd9Sstevel@tonic-gate extern char *mctag; /* from main.c */ 52*7c478bd9Sstevel@tonic-gate extern char *sctag; /* from main.c */ 53*7c478bd9Sstevel@tonic-gate extern char *premsg; /* from main.c */ 54*7c478bd9Sstevel@tonic-gate extern char *sufmsg; /* from main.c */ 55*7c478bd9Sstevel@tonic-gate extern int suppress_error; /* from main.c */ 56*7c478bd9Sstevel@tonic-gate extern void warning(char *); /* from genmsg.l */ 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate typedef struct _SetID *SetID; 59*7c478bd9Sstevel@tonic-gate typedef struct _MsgID *MsgID; 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate typedef struct _SetID SetIDRec; 62*7c478bd9Sstevel@tonic-gate struct _SetID { 63*7c478bd9Sstevel@tonic-gate int id; 64*7c478bd9Sstevel@tonic-gate char *comment; 65*7c478bd9Sstevel@tonic-gate MsgID top; 66*7c478bd9Sstevel@tonic-gate SetID next; 67*7c478bd9Sstevel@tonic-gate }; 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate typedef struct _MsgID MsgIDRec; 70*7c478bd9Sstevel@tonic-gate struct _MsgID { 71*7c478bd9Sstevel@tonic-gate int no_write; 72*7c478bd9Sstevel@tonic-gate int id; 73*7c478bd9Sstevel@tonic-gate char *msg; 74*7c478bd9Sstevel@tonic-gate int line; 75*7c478bd9Sstevel@tonic-gate char *file; 76*7c478bd9Sstevel@tonic-gate char *comment; 77*7c478bd9Sstevel@tonic-gate MsgID next; 78*7c478bd9Sstevel@tonic-gate }; 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate /* Top pointer of the setid list. */ 82*7c478bd9Sstevel@tonic-gate static SetID setid_top; 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate /* comment for messages. */ 85*7c478bd9Sstevel@tonic-gate static char *msg_comment; 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate /* comment for set numbers. */ 88*7c478bd9Sstevel@tonic-gate static char *set_comment; 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate /* List of set number's maximum message numbers. */ 91*7c478bd9Sstevel@tonic-gate static int msgid_table[NL_SETMAX+1]; 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate /* Quote character to surround messages. */ 94*7c478bd9Sstevel@tonic-gate static char quote = QUOTE; 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate /* Internal functions. */ 97*7c478bd9Sstevel@tonic-gate static void add_msgid(SetID, int, char *, char *, int, int); 98*7c478bd9Sstevel@tonic-gate static void add_setid(int, int, char *, char *, int, int); 99*7c478bd9Sstevel@tonic-gate static SetID lookup_setid(int); 100*7c478bd9Sstevel@tonic-gate static MsgID lookup_msgid(SetID, int, char *, char *, int); 101*7c478bd9Sstevel@tonic-gate static void print_prefix(FILE *, char *, int, char *); 102*7c478bd9Sstevel@tonic-gate static int is_bs_terminated(char *); 103*7c478bd9Sstevel@tonic-gate static char *ustrdup(char *); 104*7c478bd9Sstevel@tonic-gate static void cat_msg(char *, char *, int); 105*7c478bd9Sstevel@tonic-gate static void makeup_msg(char **); 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate void 108*7c478bd9Sstevel@tonic-gate add_msg(int setid, int msgid, char *msg, char *file, int line, int no_write) 109*7c478bd9Sstevel@tonic-gate { 110*7c478bd9Sstevel@tonic-gate SetID si; 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate if (si = lookup_setid(setid)) { 113*7c478bd9Sstevel@tonic-gate if (lookup_msgid(si, msgid, msg, file, line)) { 114*7c478bd9Sstevel@tonic-gate return; /* we already have the one. */ 115*7c478bd9Sstevel@tonic-gate } else { 116*7c478bd9Sstevel@tonic-gate add_msgid(si, msgid, msg, file, line, no_write); 117*7c478bd9Sstevel@tonic-gate } 118*7c478bd9Sstevel@tonic-gate } else { 119*7c478bd9Sstevel@tonic-gate add_setid(setid, msgid, msg, file, line, no_write); 120*7c478bd9Sstevel@tonic-gate } 121*7c478bd9Sstevel@tonic-gate } 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate int 124*7c478bd9Sstevel@tonic-gate is_writable(char *file) 125*7c478bd9Sstevel@tonic-gate { 126*7c478bd9Sstevel@tonic-gate struct stat buf; 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate if (stat(file, &buf) == -1) 129*7c478bd9Sstevel@tonic-gate return (TRUE); 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate if (access(file, W_OK) == 0) 132*7c478bd9Sstevel@tonic-gate return (TRUE); 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate return (FALSE); 135*7c478bd9Sstevel@tonic-gate } 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate void 138*7c478bd9Sstevel@tonic-gate write_msgfile(char *file) 139*7c478bd9Sstevel@tonic-gate { 140*7c478bd9Sstevel@tonic-gate FILE *fp; 141*7c478bd9Sstevel@tonic-gate SetID si = setid_top; 142*7c478bd9Sstevel@tonic-gate char *mode = "w"; 143*7c478bd9Sstevel@tonic-gate char pquote[2]; 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate if (is_writable(file) == FALSE) { 146*7c478bd9Sstevel@tonic-gate prg_err(gettext("cannot create \"%s\": permission denied"), 147*7c478bd9Sstevel@tonic-gate file); 148*7c478bd9Sstevel@tonic-gate return; 149*7c478bd9Sstevel@tonic-gate } 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate if (IsActiveMode(AppendMode)) { 152*7c478bd9Sstevel@tonic-gate mode = "a"; 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate if ((fp = fopen(file, mode)) == NULL) { 156*7c478bd9Sstevel@tonic-gate prg_err(gettext("cannot create \"%s\""), file); 157*7c478bd9Sstevel@tonic-gate return; 158*7c478bd9Sstevel@tonic-gate } 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate if (quote) { 161*7c478bd9Sstevel@tonic-gate (void) sprintf(pquote, "%c", quote); 162*7c478bd9Sstevel@tonic-gate } else { 163*7c478bd9Sstevel@tonic-gate (void) sprintf(pquote, ""); 164*7c478bd9Sstevel@tonic-gate } 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate /* AppendMode is already turned off if the file doesn't exist. */ 167*7c478bd9Sstevel@tonic-gate if (!IsActiveMode(AppendMode)) { 168*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\n$quote %s\n\n", pquote); 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate while (si) { 172*7c478bd9Sstevel@tonic-gate int is_set = FALSE; 173*7c478bd9Sstevel@tonic-gate MsgID mi = si->top; 174*7c478bd9Sstevel@tonic-gate while (mi) { 175*7c478bd9Sstevel@tonic-gate char msg[NL_TEXTMAX+32]; /* 32 is some other stuff. */ 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate if (mi->no_write) { 178*7c478bd9Sstevel@tonic-gate mi = mi->next; 179*7c478bd9Sstevel@tonic-gate continue; 180*7c478bd9Sstevel@tonic-gate } 181*7c478bd9Sstevel@tonic-gate if (is_set == FALSE) { 182*7c478bd9Sstevel@tonic-gate if (si->comment && 183*7c478bd9Sstevel@tonic-gate !IsActiveMode(BackCommentMode)) { 184*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\n"); 185*7c478bd9Sstevel@tonic-gate print_prefix(fp, "$ ", TRUE, 186*7c478bd9Sstevel@tonic-gate si->comment); 187*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "$set\t%d\n", 188*7c478bd9Sstevel@tonic-gate si->id); 189*7c478bd9Sstevel@tonic-gate } else { 190*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\n$set\t%d\n", 191*7c478bd9Sstevel@tonic-gate si->id); 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate if (si->comment && 194*7c478bd9Sstevel@tonic-gate IsActiveMode(BackCommentMode)) { 195*7c478bd9Sstevel@tonic-gate print_prefix(fp, "$ ", TRUE, 196*7c478bd9Sstevel@tonic-gate si->comment); 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\n"); 199*7c478bd9Sstevel@tonic-gate is_set = TRUE; 200*7c478bd9Sstevel@tonic-gate } 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate makeup_msg(&(mi->msg)); 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate (void) sprintf(msg, "%d\t%s%s%s\n", 205*7c478bd9Sstevel@tonic-gate mi->id, pquote, mi->msg, pquote); 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate if (!IsActiveMode(BackCommentMode)) { 208*7c478bd9Sstevel@tonic-gate if (mi->line && mi->file && 209*7c478bd9Sstevel@tonic-gate IsActiveMode(LineInfoMode)) { 210*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, 211*7c478bd9Sstevel@tonic-gate "$ File:%s, line:%d\n", 212*7c478bd9Sstevel@tonic-gate basename(mi->file), mi->line); 213*7c478bd9Sstevel@tonic-gate } 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate if (mi->comment) { 216*7c478bd9Sstevel@tonic-gate print_prefix(fp, "$ ", TRUE, 217*7c478bd9Sstevel@tonic-gate mi->comment); 218*7c478bd9Sstevel@tonic-gate } 219*7c478bd9Sstevel@tonic-gate 220*7c478bd9Sstevel@tonic-gate if (IsActiveMode(DoubleLineMode)) { 221*7c478bd9Sstevel@tonic-gate print_prefix(fp, "$ ", FALSE, msg); 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate } 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s", msg); 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate if (IsActiveMode(BackCommentMode)) { 228*7c478bd9Sstevel@tonic-gate if (mi->line && mi->file && 229*7c478bd9Sstevel@tonic-gate IsActiveMode(LineInfoMode)) { 230*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, 231*7c478bd9Sstevel@tonic-gate "$ File:%s, line:%d\n", 232*7c478bd9Sstevel@tonic-gate basename(mi->file), mi->line); 233*7c478bd9Sstevel@tonic-gate } 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate if (mi->comment) { 236*7c478bd9Sstevel@tonic-gate print_prefix(fp, "$ ", TRUE, 237*7c478bd9Sstevel@tonic-gate mi->comment); 238*7c478bd9Sstevel@tonic-gate } 239*7c478bd9Sstevel@tonic-gate 240*7c478bd9Sstevel@tonic-gate if (IsActiveMode(DoubleLineMode)) { 241*7c478bd9Sstevel@tonic-gate print_prefix(fp, "$ ", FALSE, msg); 242*7c478bd9Sstevel@tonic-gate } 243*7c478bd9Sstevel@tonic-gate } 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\n"); 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate mi = mi->next; 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate si = si->next; 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 253*7c478bd9Sstevel@tonic-gate } 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate static SetID 256*7c478bd9Sstevel@tonic-gate lookup_setid(int id) 257*7c478bd9Sstevel@tonic-gate { 258*7c478bd9Sstevel@tonic-gate SetID si = setid_top; 259*7c478bd9Sstevel@tonic-gate while (si) { 260*7c478bd9Sstevel@tonic-gate if (si->id == id) { 261*7c478bd9Sstevel@tonic-gate return (si); 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate si = si->next; 264*7c478bd9Sstevel@tonic-gate } 265*7c478bd9Sstevel@tonic-gate return (NULL); 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate static MsgID 269*7c478bd9Sstevel@tonic-gate lookup_msgid(SetID si, int msgid, char *msg, char *file, int line) 270*7c478bd9Sstevel@tonic-gate { 271*7c478bd9Sstevel@tonic-gate MsgID mi = si->top; 272*7c478bd9Sstevel@tonic-gate while (mi) { 273*7c478bd9Sstevel@tonic-gate if (mi->id == msgid) { 274*7c478bd9Sstevel@tonic-gate /* same setid & msgid, but different msg. */ 275*7c478bd9Sstevel@tonic-gate if (strcmp(mi->msg, msg)) { 276*7c478bd9Sstevel@tonic-gate src_err(file, line, 277*7c478bd9Sstevel@tonic-gate gettext("multiple messages: set number %d, message number %d\n" 278*7c478bd9Sstevel@tonic-gate " current : \"%s\"\n" 279*7c478bd9Sstevel@tonic-gate " previous: \"%s\" : \"%s\", line %d"), 280*7c478bd9Sstevel@tonic-gate si->id, mi->id, 281*7c478bd9Sstevel@tonic-gate msg, 282*7c478bd9Sstevel@tonic-gate mi->msg, mi->file, mi->line); 283*7c478bd9Sstevel@tonic-gate } 284*7c478bd9Sstevel@tonic-gate return (mi); 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate mi = mi->next; 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate return (NULL); 289*7c478bd9Sstevel@tonic-gate } 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate static void 292*7c478bd9Sstevel@tonic-gate add_msgid(SetID si, int msgid, char *msg, char *file, int line, int no_write) 293*7c478bd9Sstevel@tonic-gate { 294*7c478bd9Sstevel@tonic-gate MsgID mi = si->top, newmi, prev = NULL; 295*7c478bd9Sstevel@tonic-gate int len = strlen(msg); 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate if (msgid == 0) { 298*7c478bd9Sstevel@tonic-gate src_err(file, line, gettext("improper message number: %d"), 299*7c478bd9Sstevel@tonic-gate msgid); 300*7c478bd9Sstevel@tonic-gate return; 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate if (msgid > NL_MSGMAX) { 304*7c478bd9Sstevel@tonic-gate src_err(file, line, gettext("too large message number: %d"), 305*7c478bd9Sstevel@tonic-gate msgid); 306*7c478bd9Sstevel@tonic-gate return; 307*7c478bd9Sstevel@tonic-gate } 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate if (len > NL_TEXTMAX) { 310*7c478bd9Sstevel@tonic-gate src_err(file, line, gettext("too long message text")); 311*7c478bd9Sstevel@tonic-gate return; 312*7c478bd9Sstevel@tonic-gate } 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate while (mi) { 315*7c478bd9Sstevel@tonic-gate if (mi->id > msgid) { 316*7c478bd9Sstevel@tonic-gate break; 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate prev = mi; 319*7c478bd9Sstevel@tonic-gate mi = mi->next; 320*7c478bd9Sstevel@tonic-gate } 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate if ((newmi = (MsgID) malloc(sizeof (MsgIDRec))) == NULL) { 323*7c478bd9Sstevel@tonic-gate prg_err(gettext("fatal: out of memory")); 324*7c478bd9Sstevel@tonic-gate exit(EXIT_FAILURE); 325*7c478bd9Sstevel@tonic-gate } 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate newmi->no_write = no_write; 328*7c478bd9Sstevel@tonic-gate newmi->id = msgid; 329*7c478bd9Sstevel@tonic-gate newmi->msg = (char *) ustrdup(msg); 330*7c478bd9Sstevel@tonic-gate newmi->file = (char *) ustrdup(file); 331*7c478bd9Sstevel@tonic-gate newmi->line = line; 332*7c478bd9Sstevel@tonic-gate newmi->next = mi; 333*7c478bd9Sstevel@tonic-gate 334*7c478bd9Sstevel@tonic-gate if (msg_comment) { 335*7c478bd9Sstevel@tonic-gate newmi->comment = (char *) ustrdup(msg_comment); 336*7c478bd9Sstevel@tonic-gate free(msg_comment); 337*7c478bd9Sstevel@tonic-gate msg_comment = NULL; 338*7c478bd9Sstevel@tonic-gate } else { 339*7c478bd9Sstevel@tonic-gate newmi->comment = NULL; 340*7c478bd9Sstevel@tonic-gate } 341*7c478bd9Sstevel@tonic-gate 342*7c478bd9Sstevel@tonic-gate if (prev == NULL) { 343*7c478bd9Sstevel@tonic-gate si->top = newmi; 344*7c478bd9Sstevel@tonic-gate } else { 345*7c478bd9Sstevel@tonic-gate prev->next = newmi; 346*7c478bd9Sstevel@tonic-gate } 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate static void 350*7c478bd9Sstevel@tonic-gate add_setid(int setid, int msgid, char *msg, char *file, int line, int no_write) 351*7c478bd9Sstevel@tonic-gate { 352*7c478bd9Sstevel@tonic-gate SetID si = setid_top, newsi, prev = NULL; 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate while (si) { 355*7c478bd9Sstevel@tonic-gate if (si->id > setid) { 356*7c478bd9Sstevel@tonic-gate break; 357*7c478bd9Sstevel@tonic-gate } 358*7c478bd9Sstevel@tonic-gate prev = si; 359*7c478bd9Sstevel@tonic-gate si = si->next; 360*7c478bd9Sstevel@tonic-gate } 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate if ((newsi = (SetID) malloc(sizeof (SetIDRec))) == NULL) { 363*7c478bd9Sstevel@tonic-gate prg_err(gettext("fatal: out of memory")); 364*7c478bd9Sstevel@tonic-gate exit(EXIT_FAILURE); 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate newsi->id = setid; 368*7c478bd9Sstevel@tonic-gate newsi->top = NULL; 369*7c478bd9Sstevel@tonic-gate newsi->next = si; 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate if (set_comment) { 372*7c478bd9Sstevel@tonic-gate newsi->comment = (char *) ustrdup(set_comment); 373*7c478bd9Sstevel@tonic-gate free(set_comment); 374*7c478bd9Sstevel@tonic-gate set_comment = NULL; 375*7c478bd9Sstevel@tonic-gate } else { 376*7c478bd9Sstevel@tonic-gate newsi->comment = NULL; 377*7c478bd9Sstevel@tonic-gate } 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate if (prev == NULL) { 380*7c478bd9Sstevel@tonic-gate setid_top = newsi; 381*7c478bd9Sstevel@tonic-gate } else { 382*7c478bd9Sstevel@tonic-gate prev->next = newsi; 383*7c478bd9Sstevel@tonic-gate } 384*7c478bd9Sstevel@tonic-gate 385*7c478bd9Sstevel@tonic-gate add_msgid(newsi, msgid, msg, file, line, no_write); 386*7c478bd9Sstevel@tonic-gate } 387*7c478bd9Sstevel@tonic-gate 388*7c478bd9Sstevel@tonic-gate static void 389*7c478bd9Sstevel@tonic-gate print_prefix(FILE *fp, char *prefix, int rm_blank, char *str) 390*7c478bd9Sstevel@tonic-gate { 391*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s", prefix); 392*7c478bd9Sstevel@tonic-gate while (*str) { 393*7c478bd9Sstevel@tonic-gate (void) fputc(*str, fp); 394*7c478bd9Sstevel@tonic-gate if (*str == '\n' && *(str+1) != '\0') { 395*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s", prefix); 396*7c478bd9Sstevel@tonic-gate if (rm_blank == TRUE) { 397*7c478bd9Sstevel@tonic-gate str++; 398*7c478bd9Sstevel@tonic-gate SkipSpace(str); 399*7c478bd9Sstevel@tonic-gate continue; 400*7c478bd9Sstevel@tonic-gate } 401*7c478bd9Sstevel@tonic-gate } 402*7c478bd9Sstevel@tonic-gate str++; 403*7c478bd9Sstevel@tonic-gate } 404*7c478bd9Sstevel@tonic-gate if (*(str-1) != '\n') { 405*7c478bd9Sstevel@tonic-gate (void) fputc('\n', fp); 406*7c478bd9Sstevel@tonic-gate } 407*7c478bd9Sstevel@tonic-gate } 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate int 410*7c478bd9Sstevel@tonic-gate read_projfile(char *file) 411*7c478bd9Sstevel@tonic-gate { 412*7c478bd9Sstevel@tonic-gate FILE *fp; 413*7c478bd9Sstevel@tonic-gate char line[LINE_MAX]; 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate if (!file) { 416*7c478bd9Sstevel@tonic-gate return (0); 417*7c478bd9Sstevel@tonic-gate } 418*7c478bd9Sstevel@tonic-gate 419*7c478bd9Sstevel@tonic-gate if ((fp = fopen(file, "r")) == NULL) { 420*7c478bd9Sstevel@tonic-gate return (0); 421*7c478bd9Sstevel@tonic-gate } 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate while (fgets(line, LINE_MAX, fp) != NULL) { 424*7c478bd9Sstevel@tonic-gate char *p = line; 425*7c478bd9Sstevel@tonic-gate int n, setid, msgid; 426*7c478bd9Sstevel@tonic-gate 427*7c478bd9Sstevel@tonic-gate SkipSpace(p); 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate if (*p == '#' || *p == '\n') { 430*7c478bd9Sstevel@tonic-gate continue; 431*7c478bd9Sstevel@tonic-gate } 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate n = sscanf(p, "%d %d", &setid, &msgid); 434*7c478bd9Sstevel@tonic-gate 435*7c478bd9Sstevel@tonic-gate if (n == 2) { 436*7c478bd9Sstevel@tonic-gate if (setid > NL_SETMAX) { 437*7c478bd9Sstevel@tonic-gate prg_err(gettext("%s: too large set number: %d"), 438*7c478bd9Sstevel@tonic-gate file, setid); 439*7c478bd9Sstevel@tonic-gate continue; 440*7c478bd9Sstevel@tonic-gate } 441*7c478bd9Sstevel@tonic-gate msgid_table[setid] = msgid; 442*7c478bd9Sstevel@tonic-gate } else { 443*7c478bd9Sstevel@tonic-gate prg_err( 444*7c478bd9Sstevel@tonic-gate /* for stupid cstyle */ 445*7c478bd9Sstevel@tonic-gate gettext("warning: %s: missing or invalid entry"), 446*7c478bd9Sstevel@tonic-gate file); 447*7c478bd9Sstevel@tonic-gate } 448*7c478bd9Sstevel@tonic-gate } 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate return (1); 453*7c478bd9Sstevel@tonic-gate } 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate void 456*7c478bd9Sstevel@tonic-gate write_projfile(char *file) 457*7c478bd9Sstevel@tonic-gate { 458*7c478bd9Sstevel@tonic-gate FILE *fp; 459*7c478bd9Sstevel@tonic-gate register int i; 460*7c478bd9Sstevel@tonic-gate 461*7c478bd9Sstevel@tonic-gate if (is_writable(file) == FALSE) { 462*7c478bd9Sstevel@tonic-gate prg_err(gettext("cannot create \"%s\": permission denied"), 463*7c478bd9Sstevel@tonic-gate file); 464*7c478bd9Sstevel@tonic-gate return; 465*7c478bd9Sstevel@tonic-gate } 466*7c478bd9Sstevel@tonic-gate 467*7c478bd9Sstevel@tonic-gate if ((fp = fopen(file, "w")) == NULL) { 468*7c478bd9Sstevel@tonic-gate prg_err(gettext("cannot create \"%s\""), file); 469*7c478bd9Sstevel@tonic-gate return; 470*7c478bd9Sstevel@tonic-gate } 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate for (i = 1; i <= NL_SETMAX; i++) { 473*7c478bd9Sstevel@tonic-gate if (msgid_table[i] > 0) { 474*7c478bd9Sstevel@tonic-gate SetID si; 475*7c478bd9Sstevel@tonic-gate char *com = NULL; 476*7c478bd9Sstevel@tonic-gate 477*7c478bd9Sstevel@tonic-gate if (IsActiveMode(SetCommentMode) && 478*7c478bd9Sstevel@tonic-gate (si = lookup_setid(i)) && si->comment) { 479*7c478bd9Sstevel@tonic-gate com = si->comment; 480*7c478bd9Sstevel@tonic-gate } 481*7c478bd9Sstevel@tonic-gate 482*7c478bd9Sstevel@tonic-gate if (com && !IsActiveMode(BackCommentMode)) { 483*7c478bd9Sstevel@tonic-gate print_prefix(fp, "# ", TRUE, com); 484*7c478bd9Sstevel@tonic-gate } 485*7c478bd9Sstevel@tonic-gate 486*7c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%d\t%d\n", i, msgid_table[i]); 487*7c478bd9Sstevel@tonic-gate 488*7c478bd9Sstevel@tonic-gate if (com && IsActiveMode(BackCommentMode)) { 489*7c478bd9Sstevel@tonic-gate print_prefix(fp, "# ", TRUE, com); 490*7c478bd9Sstevel@tonic-gate } 491*7c478bd9Sstevel@tonic-gate } 492*7c478bd9Sstevel@tonic-gate } 493*7c478bd9Sstevel@tonic-gate 494*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 495*7c478bd9Sstevel@tonic-gate } 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate int 498*7c478bd9Sstevel@tonic-gate get_msgid(char *file, int line, int setid, char *str) 499*7c478bd9Sstevel@tonic-gate { 500*7c478bd9Sstevel@tonic-gate SetID si = setid_top; 501*7c478bd9Sstevel@tonic-gate int id = msgid_table[setid]; 502*7c478bd9Sstevel@tonic-gate 503*7c478bd9Sstevel@tonic-gate while (si) { 504*7c478bd9Sstevel@tonic-gate if (si->id == setid) { 505*7c478bd9Sstevel@tonic-gate MsgID mi = si->top; 506*7c478bd9Sstevel@tonic-gate while (mi) { 507*7c478bd9Sstevel@tonic-gate if (strcmp(mi->msg, str) == 0) { 508*7c478bd9Sstevel@tonic-gate return (mi->id); 509*7c478bd9Sstevel@tonic-gate } 510*7c478bd9Sstevel@tonic-gate mi = mi->next; 511*7c478bd9Sstevel@tonic-gate } 512*7c478bd9Sstevel@tonic-gate } 513*7c478bd9Sstevel@tonic-gate si = si->next; 514*7c478bd9Sstevel@tonic-gate } 515*7c478bd9Sstevel@tonic-gate 516*7c478bd9Sstevel@tonic-gate id++; 517*7c478bd9Sstevel@tonic-gate 518*7c478bd9Sstevel@tonic-gate if (id > NL_MSGMAX) { 519*7c478bd9Sstevel@tonic-gate src_err(file, line, 520*7c478bd9Sstevel@tonic-gate gettext("run out of message number in set number: %d"), 521*7c478bd9Sstevel@tonic-gate setid); 522*7c478bd9Sstevel@tonic-gate return (NOMSGID); 523*7c478bd9Sstevel@tonic-gate } 524*7c478bd9Sstevel@tonic-gate 525*7c478bd9Sstevel@tonic-gate return (msgid_table[setid] = id); 526*7c478bd9Sstevel@tonic-gate } 527*7c478bd9Sstevel@tonic-gate 528*7c478bd9Sstevel@tonic-gate void 529*7c478bd9Sstevel@tonic-gate set_msgid(int setid, int msgid) 530*7c478bd9Sstevel@tonic-gate { 531*7c478bd9Sstevel@tonic-gate if (msgid_table[setid] < msgid) { 532*7c478bd9Sstevel@tonic-gate msgid_table[setid] = msgid; 533*7c478bd9Sstevel@tonic-gate } 534*7c478bd9Sstevel@tonic-gate } 535*7c478bd9Sstevel@tonic-gate 536*7c478bd9Sstevel@tonic-gate void 537*7c478bd9Sstevel@tonic-gate add_comment(Mode mode, char *str) 538*7c478bd9Sstevel@tonic-gate { 539*7c478bd9Sstevel@tonic-gate char *tag = (mode == MsgCommentMode) ? mctag : sctag; 540*7c478bd9Sstevel@tonic-gate char **comment = (mode == MsgCommentMode) 541*7c478bd9Sstevel@tonic-gate ? &msg_comment : &set_comment; 542*7c478bd9Sstevel@tonic-gate 543*7c478bd9Sstevel@tonic-gate if (!strstr(str, tag)) { 544*7c478bd9Sstevel@tonic-gate return; 545*7c478bd9Sstevel@tonic-gate } 546*7c478bd9Sstevel@tonic-gate 547*7c478bd9Sstevel@tonic-gate if (*comment) { 548*7c478bd9Sstevel@tonic-gate free(*comment); 549*7c478bd9Sstevel@tonic-gate } 550*7c478bd9Sstevel@tonic-gate 551*7c478bd9Sstevel@tonic-gate *comment = (char *) ustrdup(str); 552*7c478bd9Sstevel@tonic-gate } 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate void 555*7c478bd9Sstevel@tonic-gate read_msgfile(char *file) 556*7c478bd9Sstevel@tonic-gate { 557*7c478bd9Sstevel@tonic-gate FILE *fp; 558*7c478bd9Sstevel@tonic-gate char c = 0; 559*7c478bd9Sstevel@tonic-gate int line = 0; 560*7c478bd9Sstevel@tonic-gate int inmsg = FALSE; 561*7c478bd9Sstevel@tonic-gate int setid = 0, unsetid = -1, msgid = 0; 562*7c478bd9Sstevel@tonic-gate struct stat buf; 563*7c478bd9Sstevel@tonic-gate 564*7c478bd9Sstevel@tonic-gate if ((fp = fopen(file, "r")) == NULL) { 565*7c478bd9Sstevel@tonic-gate prg_err(gettext("cannot open \"%s\""), file); 566*7c478bd9Sstevel@tonic-gate ResetActiveMode(AppendMode); 567*7c478bd9Sstevel@tonic-gate return; 568*7c478bd9Sstevel@tonic-gate } 569*7c478bd9Sstevel@tonic-gate 570*7c478bd9Sstevel@tonic-gate if (stat(file, &buf) == -1 && buf.st_size == 0) { 571*7c478bd9Sstevel@tonic-gate ResetActiveMode(AppendMode); 572*7c478bd9Sstevel@tonic-gate return; 573*7c478bd9Sstevel@tonic-gate } 574*7c478bd9Sstevel@tonic-gate 575*7c478bd9Sstevel@tonic-gate quote = c; 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 578*7c478bd9Sstevel@tonic-gate while (1) { 579*7c478bd9Sstevel@tonic-gate char buf[LINE_MAX]; 580*7c478bd9Sstevel@tonic-gate char *ptr; 581*7c478bd9Sstevel@tonic-gate char msg[NL_TEXTMAX]; 582*7c478bd9Sstevel@tonic-gate 583*7c478bd9Sstevel@tonic-gate if (fgets(buf, sizeof (buf), fp) == NULL) { 584*7c478bd9Sstevel@tonic-gate break; 585*7c478bd9Sstevel@tonic-gate } 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate line++; 588*7c478bd9Sstevel@tonic-gate 589*7c478bd9Sstevel@tonic-gate ptr = &buf[0]; 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate SkipSpace(ptr); 592*7c478bd9Sstevel@tonic-gate 593*7c478bd9Sstevel@tonic-gate if ((*ptr == '$' && (*(ptr+1) == ' ' || *(ptr+1) == '\t')) || 594*7c478bd9Sstevel@tonic-gate ((*ptr == '\n') && inmsg == FALSE)) { 595*7c478bd9Sstevel@tonic-gate inmsg = FALSE; 596*7c478bd9Sstevel@tonic-gate continue; 597*7c478bd9Sstevel@tonic-gate } 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate if (strncmp(ptr, SET_TOKEN, sizeof (SET_TOKEN) - 1) == 0) { 600*7c478bd9Sstevel@tonic-gate if (sscanf(ptr, "%*s %d", &setid) != 1) { 601*7c478bd9Sstevel@tonic-gate setid = 0; 602*7c478bd9Sstevel@tonic-gate } 603*7c478bd9Sstevel@tonic-gate inmsg = FALSE; 604*7c478bd9Sstevel@tonic-gate continue; 605*7c478bd9Sstevel@tonic-gate } else if (strncmp(ptr, DELSET_TOKEN, 606*7c478bd9Sstevel@tonic-gate sizeof (DELSET_TOKEN) - 1) == 0) { 607*7c478bd9Sstevel@tonic-gate if (sscanf(ptr, "%*s %d", &unsetid) != 1) { 608*7c478bd9Sstevel@tonic-gate unsetid = -1; 609*7c478bd9Sstevel@tonic-gate } 610*7c478bd9Sstevel@tonic-gate inmsg = FALSE; 611*7c478bd9Sstevel@tonic-gate continue; 612*7c478bd9Sstevel@tonic-gate } else if (strncmp(ptr, QUOTE_TOKEN, 613*7c478bd9Sstevel@tonic-gate sizeof (QUOTE_TOKEN) - 1) == 0) { 614*7c478bd9Sstevel@tonic-gate if (sscanf(ptr, "%*s %c", &c) != 1) { 615*7c478bd9Sstevel@tonic-gate c = 0; 616*7c478bd9Sstevel@tonic-gate } 617*7c478bd9Sstevel@tonic-gate quote = c; 618*7c478bd9Sstevel@tonic-gate inmsg = FALSE; 619*7c478bd9Sstevel@tonic-gate continue; 620*7c478bd9Sstevel@tonic-gate } 621*7c478bd9Sstevel@tonic-gate 622*7c478bd9Sstevel@tonic-gate if (setid == unsetid) { 623*7c478bd9Sstevel@tonic-gate continue; 624*7c478bd9Sstevel@tonic-gate } 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate if (inmsg) { 627*7c478bd9Sstevel@tonic-gate if (is_bs_terminated(ptr)) { 628*7c478bd9Sstevel@tonic-gate (void) strcat(msg, ptr); 629*7c478bd9Sstevel@tonic-gate inmsg = TRUE; 630*7c478bd9Sstevel@tonic-gate } else { 631*7c478bd9Sstevel@tonic-gate int len = strlen(ptr); 632*7c478bd9Sstevel@tonic-gate *(ptr + len - 1) = '\0'; 633*7c478bd9Sstevel@tonic-gate if (c && (*(ptr + len - 2) == c)) { 634*7c478bd9Sstevel@tonic-gate *(ptr + len - 2) = '\0'; 635*7c478bd9Sstevel@tonic-gate } 636*7c478bd9Sstevel@tonic-gate (void) strcat(msg, ptr); 637*7c478bd9Sstevel@tonic-gate add_msg(setid, msgid, msg, file, line, TRUE); 638*7c478bd9Sstevel@tonic-gate inmsg = FALSE; 639*7c478bd9Sstevel@tonic-gate } 640*7c478bd9Sstevel@tonic-gate continue; 641*7c478bd9Sstevel@tonic-gate } 642*7c478bd9Sstevel@tonic-gate 643*7c478bd9Sstevel@tonic-gate if (isdigit(*ptr)) { 644*7c478bd9Sstevel@tonic-gate char tmp[32]; 645*7c478bd9Sstevel@tonic-gate int i = 0; 646*7c478bd9Sstevel@tonic-gate 647*7c478bd9Sstevel@tonic-gate SkipSpace(ptr); 648*7c478bd9Sstevel@tonic-gate 649*7c478bd9Sstevel@tonic-gate while (isdigit(*ptr)) { 650*7c478bd9Sstevel@tonic-gate tmp[i++] = *ptr++; 651*7c478bd9Sstevel@tonic-gate } 652*7c478bd9Sstevel@tonic-gate tmp[i] = '\0'; 653*7c478bd9Sstevel@tonic-gate msgid = atoi(tmp); 654*7c478bd9Sstevel@tonic-gate 655*7c478bd9Sstevel@tonic-gate SkipSpace(ptr); 656*7c478bd9Sstevel@tonic-gate 657*7c478bd9Sstevel@tonic-gate if (is_bs_terminated(ptr)) { 658*7c478bd9Sstevel@tonic-gate (void) memset(msg, 0, NL_TEXTMAX); 659*7c478bd9Sstevel@tonic-gate if (c && (*ptr == c)) { 660*7c478bd9Sstevel@tonic-gate ptr++; 661*7c478bd9Sstevel@tonic-gate } 662*7c478bd9Sstevel@tonic-gate (void) strcpy(msg, ptr); 663*7c478bd9Sstevel@tonic-gate inmsg = TRUE; 664*7c478bd9Sstevel@tonic-gate } else { 665*7c478bd9Sstevel@tonic-gate int len = strlen(ptr); 666*7c478bd9Sstevel@tonic-gate *(ptr + len - 1) = '\0'; 667*7c478bd9Sstevel@tonic-gate if (c && ((*ptr == c) && 668*7c478bd9Sstevel@tonic-gate (*(ptr + len - 2) == c))) { 669*7c478bd9Sstevel@tonic-gate *(ptr + len - 2) = '\0'; 670*7c478bd9Sstevel@tonic-gate ptr++; 671*7c478bd9Sstevel@tonic-gate } 672*7c478bd9Sstevel@tonic-gate add_msg(setid, msgid, ptr, file, line, TRUE); 673*7c478bd9Sstevel@tonic-gate inmsg = FALSE; 674*7c478bd9Sstevel@tonic-gate } 675*7c478bd9Sstevel@tonic-gate } 676*7c478bd9Sstevel@tonic-gate } 677*7c478bd9Sstevel@tonic-gate 678*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 679*7c478bd9Sstevel@tonic-gate } 680*7c478bd9Sstevel@tonic-gate 681*7c478bd9Sstevel@tonic-gate static int 682*7c478bd9Sstevel@tonic-gate is_bs_terminated(char *msg) 683*7c478bd9Sstevel@tonic-gate { 684*7c478bd9Sstevel@tonic-gate int len = strlen(msg); 685*7c478bd9Sstevel@tonic-gate 686*7c478bd9Sstevel@tonic-gate while (--len >= 0) { 687*7c478bd9Sstevel@tonic-gate if (msg[len] == ' ' || msg[len] == '\t' || msg[len] == '\n') { 688*7c478bd9Sstevel@tonic-gate continue; 689*7c478bd9Sstevel@tonic-gate } else if (msg[len] == '\\') { 690*7c478bd9Sstevel@tonic-gate len--; 691*7c478bd9Sstevel@tonic-gate if (len >= 0 && msg[len] == '\\') 692*7c478bd9Sstevel@tonic-gate return (0); 693*7c478bd9Sstevel@tonic-gate return (1); 694*7c478bd9Sstevel@tonic-gate } else { 695*7c478bd9Sstevel@tonic-gate return (0); 696*7c478bd9Sstevel@tonic-gate } 697*7c478bd9Sstevel@tonic-gate } 698*7c478bd9Sstevel@tonic-gate return (0); 699*7c478bd9Sstevel@tonic-gate } 700*7c478bd9Sstevel@tonic-gate 701*7c478bd9Sstevel@tonic-gate static char * 702*7c478bd9Sstevel@tonic-gate ustrdup(char *str) 703*7c478bd9Sstevel@tonic-gate { 704*7c478bd9Sstevel@tonic-gate char *tmp = strdup(str); 705*7c478bd9Sstevel@tonic-gate if (!tmp) { 706*7c478bd9Sstevel@tonic-gate prg_err(gettext("fatal: out of memory")); 707*7c478bd9Sstevel@tonic-gate exit(EXIT_FAILURE); 708*7c478bd9Sstevel@tonic-gate } 709*7c478bd9Sstevel@tonic-gate return (tmp); 710*7c478bd9Sstevel@tonic-gate } 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate int 713*7c478bd9Sstevel@tonic-gate file_copy(char *in, char *out) 714*7c478bd9Sstevel@tonic-gate { 715*7c478bd9Sstevel@tonic-gate int ret = TRUE; 716*7c478bd9Sstevel@tonic-gate FILE *fin, *fout; 717*7c478bd9Sstevel@tonic-gate int c; 718*7c478bd9Sstevel@tonic-gate sigset_t newmask, oldmask; 719*7c478bd9Sstevel@tonic-gate 720*7c478bd9Sstevel@tonic-gate (void) sigemptyset(&newmask); 721*7c478bd9Sstevel@tonic-gate (void) sigaddset(&newmask, SIGQUIT); 722*7c478bd9Sstevel@tonic-gate (void) sigaddset(&newmask, SIGINT); 723*7c478bd9Sstevel@tonic-gate (void) sigaddset(&newmask, SIGHUP); 724*7c478bd9Sstevel@tonic-gate (void) sigaddset(&newmask, SIGTERM); 725*7c478bd9Sstevel@tonic-gate (void) sigprocmask(SIG_BLOCK, &newmask, &oldmask); 726*7c478bd9Sstevel@tonic-gate 727*7c478bd9Sstevel@tonic-gate if ((fin = fopen(in, "r")) == NULL) { 728*7c478bd9Sstevel@tonic-gate prg_err(gettext("cannot open \"%s\""), in); 729*7c478bd9Sstevel@tonic-gate ret = FALSE; 730*7c478bd9Sstevel@tonic-gate goto done; 731*7c478bd9Sstevel@tonic-gate } 732*7c478bd9Sstevel@tonic-gate 733*7c478bd9Sstevel@tonic-gate if ((fout = fopen(out, "w")) == NULL) { 734*7c478bd9Sstevel@tonic-gate prg_err(gettext("cannot create \"%s\""), out); 735*7c478bd9Sstevel@tonic-gate ret = FALSE; 736*7c478bd9Sstevel@tonic-gate goto done; 737*7c478bd9Sstevel@tonic-gate } 738*7c478bd9Sstevel@tonic-gate 739*7c478bd9Sstevel@tonic-gate while ((c = getc(fin)) != EOF) 740*7c478bd9Sstevel@tonic-gate (void) putc(c, fout); 741*7c478bd9Sstevel@tonic-gate 742*7c478bd9Sstevel@tonic-gate (void) fclose(fin); 743*7c478bd9Sstevel@tonic-gate (void) fclose(fout); 744*7c478bd9Sstevel@tonic-gate 745*7c478bd9Sstevel@tonic-gate done: 746*7c478bd9Sstevel@tonic-gate (void) sigprocmask(SIG_SETMASK, &oldmask, NULL); 747*7c478bd9Sstevel@tonic-gate return (ret); 748*7c478bd9Sstevel@tonic-gate } 749*7c478bd9Sstevel@tonic-gate 750*7c478bd9Sstevel@tonic-gate static void 751*7c478bd9Sstevel@tonic-gate cat_msg(char *out, char *msg, int max) 752*7c478bd9Sstevel@tonic-gate { 753*7c478bd9Sstevel@tonic-gate if (strlen(out) > max) { 754*7c478bd9Sstevel@tonic-gate return; 755*7c478bd9Sstevel@tonic-gate } 756*7c478bd9Sstevel@tonic-gate 757*7c478bd9Sstevel@tonic-gate (void) strncat(out, msg, max); 758*7c478bd9Sstevel@tonic-gate 759*7c478bd9Sstevel@tonic-gate if (strlen(out) > max) { 760*7c478bd9Sstevel@tonic-gate out[max] = '\0'; 761*7c478bd9Sstevel@tonic-gate } 762*7c478bd9Sstevel@tonic-gate } 763*7c478bd9Sstevel@tonic-gate 764*7c478bd9Sstevel@tonic-gate static void 765*7c478bd9Sstevel@tonic-gate makeup_msg(char **pmsg) 766*7c478bd9Sstevel@tonic-gate { 767*7c478bd9Sstevel@tonic-gate char buf[NL_TEXTMAX]; 768*7c478bd9Sstevel@tonic-gate char *msg; 769*7c478bd9Sstevel@tonic-gate 770*7c478bd9Sstevel@tonic-gate msg = *pmsg; 771*7c478bd9Sstevel@tonic-gate (void) memset((void *) buf, 0, NL_TEXTMAX); 772*7c478bd9Sstevel@tonic-gate 773*7c478bd9Sstevel@tonic-gate if (IsActiveMode(TripleMode) && !strchr(msg, '%')) { 774*7c478bd9Sstevel@tonic-gate /* there is no '%' in message. */ 775*7c478bd9Sstevel@tonic-gate int len = strlen(msg); 776*7c478bd9Sstevel@tonic-gate 777*7c478bd9Sstevel@tonic-gate if (msg[len-2] == '\\' && msg[len-1] == 'n') { 778*7c478bd9Sstevel@tonic-gate msg[len-2] = '\0'; 779*7c478bd9Sstevel@tonic-gate cat_msg(buf, msg, (NL_TEXTMAX - 2)); 780*7c478bd9Sstevel@tonic-gate cat_msg(buf, msg, (NL_TEXTMAX - 2)); 781*7c478bd9Sstevel@tonic-gate cat_msg(buf, msg, (NL_TEXTMAX - 2)); 782*7c478bd9Sstevel@tonic-gate cat_msg(buf, "\\n", NL_TEXTMAX); 783*7c478bd9Sstevel@tonic-gate } else { 784*7c478bd9Sstevel@tonic-gate cat_msg(buf, msg, NL_TEXTMAX); 785*7c478bd9Sstevel@tonic-gate cat_msg(buf, msg, NL_TEXTMAX); 786*7c478bd9Sstevel@tonic-gate cat_msg(buf, msg, NL_TEXTMAX); 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate free(msg); 789*7c478bd9Sstevel@tonic-gate *pmsg = (char *) ustrdup(buf); 790*7c478bd9Sstevel@tonic-gate } 791*7c478bd9Sstevel@tonic-gate 792*7c478bd9Sstevel@tonic-gate msg = *pmsg; 793*7c478bd9Sstevel@tonic-gate (void) memset((void *) buf, 0, NL_TEXTMAX); 794*7c478bd9Sstevel@tonic-gate 795*7c478bd9Sstevel@tonic-gate if (IsActiveMode(PrefixMode)) { 796*7c478bd9Sstevel@tonic-gate cat_msg(buf, premsg, NL_TEXTMAX); 797*7c478bd9Sstevel@tonic-gate cat_msg(buf, msg, NL_TEXTMAX); 798*7c478bd9Sstevel@tonic-gate free(msg); 799*7c478bd9Sstevel@tonic-gate *pmsg = (char *) ustrdup(buf); 800*7c478bd9Sstevel@tonic-gate } 801*7c478bd9Sstevel@tonic-gate 802*7c478bd9Sstevel@tonic-gate msg = *pmsg; 803*7c478bd9Sstevel@tonic-gate (void) memset((void *) buf, 0, NL_TEXTMAX); 804*7c478bd9Sstevel@tonic-gate 805*7c478bd9Sstevel@tonic-gate if (IsActiveMode(SuffixMode)) { 806*7c478bd9Sstevel@tonic-gate int len = strlen(msg); 807*7c478bd9Sstevel@tonic-gate 808*7c478bd9Sstevel@tonic-gate if (msg[len-2] == '\\' && msg[len-1] == 'n') { 809*7c478bd9Sstevel@tonic-gate msg[len-2] = '\0'; 810*7c478bd9Sstevel@tonic-gate cat_msg(buf, msg, (NL_TEXTMAX - 2)); 811*7c478bd9Sstevel@tonic-gate cat_msg(buf, sufmsg, (NL_TEXTMAX - 2)); 812*7c478bd9Sstevel@tonic-gate cat_msg(buf, "\\n", NL_TEXTMAX); 813*7c478bd9Sstevel@tonic-gate } else { 814*7c478bd9Sstevel@tonic-gate cat_msg(buf, msg, NL_TEXTMAX); 815*7c478bd9Sstevel@tonic-gate cat_msg(buf, sufmsg, NL_TEXTMAX); 816*7c478bd9Sstevel@tonic-gate } 817*7c478bd9Sstevel@tonic-gate free(msg); 818*7c478bd9Sstevel@tonic-gate *pmsg = (char *) ustrdup(buf); 819*7c478bd9Sstevel@tonic-gate } 820*7c478bd9Sstevel@tonic-gate } 821*7c478bd9Sstevel@tonic-gate 822*7c478bd9Sstevel@tonic-gate void 823*7c478bd9Sstevel@tonic-gate prg_err(char *fmt, ...) 824*7c478bd9Sstevel@tonic-gate { 825*7c478bd9Sstevel@tonic-gate va_list ap; 826*7c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 827*7c478bd9Sstevel@tonic-gate 828*7c478bd9Sstevel@tonic-gate va_start(ap, fmt); 829*7c478bd9Sstevel@tonic-gate 830*7c478bd9Sstevel@tonic-gate (void) vsprintf(buf, fmt, ap); 831*7c478bd9Sstevel@tonic-gate 832*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s\n", program, buf); 833*7c478bd9Sstevel@tonic-gate 834*7c478bd9Sstevel@tonic-gate va_end(ap); 835*7c478bd9Sstevel@tonic-gate } 836*7c478bd9Sstevel@tonic-gate 837*7c478bd9Sstevel@tonic-gate void 838*7c478bd9Sstevel@tonic-gate src_err(char *file, int line, char *fmt, ...) 839*7c478bd9Sstevel@tonic-gate { 840*7c478bd9Sstevel@tonic-gate va_list ap; 841*7c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 842*7c478bd9Sstevel@tonic-gate char sbuf[BUFSIZ/2]; 843*7c478bd9Sstevel@tonic-gate char vbuf[BUFSIZ/2]; 844*7c478bd9Sstevel@tonic-gate 845*7c478bd9Sstevel@tonic-gate if (suppress_error == TRUE) { 846*7c478bd9Sstevel@tonic-gate return; 847*7c478bd9Sstevel@tonic-gate } 848*7c478bd9Sstevel@tonic-gate 849*7c478bd9Sstevel@tonic-gate va_start(ap, fmt); 850*7c478bd9Sstevel@tonic-gate 851*7c478bd9Sstevel@tonic-gate (void) sprintf(sbuf, gettext("\"%s\", line %d: "), file, line); 852*7c478bd9Sstevel@tonic-gate (void) vsprintf(vbuf, fmt, ap); 853*7c478bd9Sstevel@tonic-gate 854*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s%s\n", sbuf, vbuf); 855*7c478bd9Sstevel@tonic-gate (void) fputs(buf, stderr); 856*7c478bd9Sstevel@tonic-gate 857*7c478bd9Sstevel@tonic-gate va_end(ap); 858*7c478bd9Sstevel@tonic-gate } 859