17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate
239fb11590Smike_s /*
249fb11590Smike_s * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
259fb11590Smike_s * Use is subject to license terms.
269fb11590Smike_s */
277c478bd9Sstevel@tonic-gate
287c478bd9Sstevel@tonic-gate #include <stdio.h>
297c478bd9Sstevel@tonic-gate #include <ctype.h>
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <sys/stat.h>
327c478bd9Sstevel@tonic-gate #include <signal.h>
339fb11590Smike_s #include <string.h>
349fb11590Smike_s #include <stdlib.h>
359fb11590Smike_s #include <unistd.h>
369fb11590Smike_s #include <stdarg.h>
377c478bd9Sstevel@tonic-gate #include "error.h"
387c478bd9Sstevel@tonic-gate
399fb11590Smike_s static void errorprint(FILE *place, Eptr errorp, boolean print_all);
409fb11590Smike_s static void text(Eptr p, boolean use_all);
419fb11590Smike_s static void insert(int place);
429fb11590Smike_s static void execvarg(int n_pissed_on, int *r_argc, char ***r_argv);
439fb11590Smike_s static void diverterrors(char *name, int dest, Eptr **files, int ix,
449fb11590Smike_s boolean previewed, int nterrors);
459fb11590Smike_s static void hackfile(char *name, Eptr **files, int ix, int nerrors);
469fb11590Smike_s static int countfiles(Eptr *errors);
479fb11590Smike_s static int nopertain(Eptr **files);
489fb11590Smike_s static int oktotouch(char *filename);
499fb11590Smike_s static boolean preview(int nerrors, Eptr **files, int ix);
509fb11590Smike_s static int settotouch(char *name);
519fb11590Smike_s static boolean edit(char *name);
529fb11590Smike_s static int mustoverwrite(FILE *preciousfile, FILE *tmpfile);
539fb11590Smike_s static int mustwrite(char *base, int n, FILE *preciousfile);
549fb11590Smike_s static void writetouched(int overwrite);
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate /*
577c478bd9Sstevel@tonic-gate * Iterate through errors
587c478bd9Sstevel@tonic-gate */
597c478bd9Sstevel@tonic-gate #define EITERATE(p, fv, i) for (p = fv[i]; p < fv[i+1]; p++)
609fb11590Smike_s #define ECITERATE(ei, p, lb) \
619fb11590Smike_s for (ei = lb; p = errors[ei], ei < nerrors; ei++)
627c478bd9Sstevel@tonic-gate
637c478bd9Sstevel@tonic-gate #define FILEITERATE(fi, lb) for (fi = lb; fi <= nfiles; fi++)
647c478bd9Sstevel@tonic-gate int touchstatus = Q_YES;
65*28ab0ca4SToomas Soome boolean *touchedfiles;
667c478bd9Sstevel@tonic-gate
679fb11590Smike_s void
findfiles(int nerrors,Eptr * errors,int * r_nfiles,Eptr *** r_files)689fb11590Smike_s findfiles(int nerrors, Eptr *errors, int *r_nfiles, Eptr ***r_files)
697c478bd9Sstevel@tonic-gate {
707c478bd9Sstevel@tonic-gate int nfiles;
717c478bd9Sstevel@tonic-gate Eptr **files;
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gate char *name;
749fb11590Smike_s int ei;
757c478bd9Sstevel@tonic-gate int fi;
769fb11590Smike_s Eptr errorp;
777c478bd9Sstevel@tonic-gate
787c478bd9Sstevel@tonic-gate nfiles = countfiles(errors);
797c478bd9Sstevel@tonic-gate
809fb11590Smike_s files = Calloc(nfiles + 3, sizeof (Eptr*));
819fb11590Smike_s touchedfiles = Calloc(nfiles+3, sizeof (boolean));
827c478bd9Sstevel@tonic-gate /*
837c478bd9Sstevel@tonic-gate * Now, partition off the error messages
847c478bd9Sstevel@tonic-gate * into those that are synchronization, discarded or
857c478bd9Sstevel@tonic-gate * not specific to any file, and those that were
867c478bd9Sstevel@tonic-gate * nulled or true errors.
877c478bd9Sstevel@tonic-gate */
887c478bd9Sstevel@tonic-gate files[0] = &errors[0];
897c478bd9Sstevel@tonic-gate ECITERATE(ei, errorp, 0) {
907c478bd9Sstevel@tonic-gate if (!(NOTSORTABLE(errorp->error_e_class)))
917c478bd9Sstevel@tonic-gate break;
927c478bd9Sstevel@tonic-gate }
937c478bd9Sstevel@tonic-gate /*
947c478bd9Sstevel@tonic-gate * Now, and partition off all error messages
957c478bd9Sstevel@tonic-gate * for a given file.
967c478bd9Sstevel@tonic-gate */
977c478bd9Sstevel@tonic-gate files[1] = &errors[ei];
987c478bd9Sstevel@tonic-gate touchedfiles[0] = touchedfiles[1] = FALSE;
997c478bd9Sstevel@tonic-gate name = "\1";
1007c478bd9Sstevel@tonic-gate fi = 1;
1017c478bd9Sstevel@tonic-gate ECITERATE(ei, errorp, ei) {
1029fb11590Smike_s if ((errorp->error_e_class == C_NULLED) ||
1039fb11590Smike_s (errorp->error_e_class == C_TRUE)) {
1047c478bd9Sstevel@tonic-gate if (strcmp(errorp->error_text[0], name) != 0) {
1057c478bd9Sstevel@tonic-gate name = errorp->error_text[0];
1067c478bd9Sstevel@tonic-gate touchedfiles[fi] = FALSE;
1077c478bd9Sstevel@tonic-gate files[fi] = &errors[ei];
1087c478bd9Sstevel@tonic-gate fi++;
1097c478bd9Sstevel@tonic-gate }
1107c478bd9Sstevel@tonic-gate }
1117c478bd9Sstevel@tonic-gate }
1127c478bd9Sstevel@tonic-gate files[fi] = &errors[nerrors];
1137c478bd9Sstevel@tonic-gate *r_nfiles = nfiles;
1147c478bd9Sstevel@tonic-gate *r_files = files;
1157c478bd9Sstevel@tonic-gate }
1167c478bd9Sstevel@tonic-gate
1179fb11590Smike_s static int
countfiles(Eptr * errors)1189fb11590Smike_s countfiles(Eptr *errors)
1197c478bd9Sstevel@tonic-gate {
1207c478bd9Sstevel@tonic-gate char *name;
1217c478bd9Sstevel@tonic-gate int ei;
1229fb11590Smike_s Eptr errorp;
1237c478bd9Sstevel@tonic-gate
1247c478bd9Sstevel@tonic-gate int nfiles;
1257c478bd9Sstevel@tonic-gate nfiles = 0;
1267c478bd9Sstevel@tonic-gate name = "\1";
1277c478bd9Sstevel@tonic-gate ECITERATE(ei, errorp, 0) {
1287c478bd9Sstevel@tonic-gate if (SORTABLE(errorp->error_e_class)) {
1297c478bd9Sstevel@tonic-gate if (strcmp(errorp->error_text[0], name) != 0) {
1307c478bd9Sstevel@tonic-gate nfiles++;
1317c478bd9Sstevel@tonic-gate name = errorp->error_text[0];
1327c478bd9Sstevel@tonic-gate }
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate return (nfiles);
1367c478bd9Sstevel@tonic-gate }
1379fb11590Smike_s
1387c478bd9Sstevel@tonic-gate char *class_table[] = {
1397c478bd9Sstevel@tonic-gate /* C_UNKNOWN 0 */ "Unknown",
1407c478bd9Sstevel@tonic-gate /* C_IGNORE 1 */ "ignore",
1417c478bd9Sstevel@tonic-gate /* C_SYNC 2 */ "synchronization",
1427c478bd9Sstevel@tonic-gate /* C_DISCARD 3 */ "discarded",
1437c478bd9Sstevel@tonic-gate /* C_NONSPEC 4 */ "non specific",
1447c478bd9Sstevel@tonic-gate /* C_THISFILE 5 */ "specific to this file",
1457c478bd9Sstevel@tonic-gate /* C_NULLED 6 */ "nulled",
1467c478bd9Sstevel@tonic-gate /* C_TRUE 7 */ "true",
1477c478bd9Sstevel@tonic-gate /* C_DUPL 8 */ "duplicated"
1487c478bd9Sstevel@tonic-gate };
1497c478bd9Sstevel@tonic-gate
1507c478bd9Sstevel@tonic-gate int class_count[C_LAST - C_FIRST] = {0};
1517c478bd9Sstevel@tonic-gate
1529fb11590Smike_s void
filenames(int nfiles,Eptr ** files)1539fb11590Smike_s filenames(int nfiles, Eptr **files)
1547c478bd9Sstevel@tonic-gate {
1559fb11590Smike_s int fi;
1567c478bd9Sstevel@tonic-gate char *sep = " ";
1577c478bd9Sstevel@tonic-gate int someerrors;
1587c478bd9Sstevel@tonic-gate
1597c478bd9Sstevel@tonic-gate /*
1607c478bd9Sstevel@tonic-gate * first, simply dump out errors that
1617c478bd9Sstevel@tonic-gate * don't pertain to any file
1627c478bd9Sstevel@tonic-gate */
1637c478bd9Sstevel@tonic-gate someerrors = nopertain(files);
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate if (nfiles) {
1667c478bd9Sstevel@tonic-gate someerrors++;
1679fb11590Smike_s (void) fprintf(stdout, terse
1687c478bd9Sstevel@tonic-gate ? "%d file%s"
1697c478bd9Sstevel@tonic-gate : "%d file%s contain%s errors",
1707c478bd9Sstevel@tonic-gate nfiles, plural(nfiles), verbform(nfiles));
1717c478bd9Sstevel@tonic-gate if (!terse) {
1727c478bd9Sstevel@tonic-gate FILEITERATE(fi, 1) {
1739fb11590Smike_s (void) fprintf(stdout, "%s\"%s\" (%d)",
1747c478bd9Sstevel@tonic-gate sep, (*files[fi])->error_text[0],
1757c478bd9Sstevel@tonic-gate files[fi+1] - files[fi]);
1767c478bd9Sstevel@tonic-gate sep = ", ";
1777c478bd9Sstevel@tonic-gate }
1787c478bd9Sstevel@tonic-gate }
1799fb11590Smike_s (void) fprintf(stdout, "\n");
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate if (!someerrors)
1829fb11590Smike_s (void) fprintf(stdout, "No errors.\n");
1837c478bd9Sstevel@tonic-gate }
1847c478bd9Sstevel@tonic-gate
1857c478bd9Sstevel@tonic-gate /*
1867c478bd9Sstevel@tonic-gate * Dump out errors that don't pertain to any file
1877c478bd9Sstevel@tonic-gate */
1889fb11590Smike_s static int
nopertain(Eptr ** files)1899fb11590Smike_s nopertain(Eptr **files)
1907c478bd9Sstevel@tonic-gate {
1917c478bd9Sstevel@tonic-gate int type;
1927c478bd9Sstevel@tonic-gate int someerrors = 0;
1939fb11590Smike_s Eptr *erpp;
1949fb11590Smike_s Eptr errorp;
1957c478bd9Sstevel@tonic-gate
1967c478bd9Sstevel@tonic-gate if (files[1] - files[0] <= 0)
1977c478bd9Sstevel@tonic-gate return (0);
1987c478bd9Sstevel@tonic-gate for (type = C_UNKNOWN; NOTSORTABLE(type); type++) {
1997c478bd9Sstevel@tonic-gate if (class_count[type] <= 0)
2007c478bd9Sstevel@tonic-gate continue;
2017c478bd9Sstevel@tonic-gate if (type > C_SYNC)
2027c478bd9Sstevel@tonic-gate someerrors++;
2037c478bd9Sstevel@tonic-gate if (terse) {
2049fb11590Smike_s (void) fprintf(stdout, "\t%d %s errors NOT PRINTED\n",
2057c478bd9Sstevel@tonic-gate class_count[type], class_table[type]);
2067c478bd9Sstevel@tonic-gate } else {
2079fb11590Smike_s (void) fprintf(stdout, "\n\t%d %s errors follow\n",
2087c478bd9Sstevel@tonic-gate class_count[type], class_table[type]);
2097c478bd9Sstevel@tonic-gate EITERATE(erpp, files, 0) {
2107c478bd9Sstevel@tonic-gate errorp = *erpp;
2117c478bd9Sstevel@tonic-gate if (errorp->error_e_class == type) {
2127c478bd9Sstevel@tonic-gate errorprint(stdout, errorp, TRUE);
2137c478bd9Sstevel@tonic-gate }
2147c478bd9Sstevel@tonic-gate }
2157c478bd9Sstevel@tonic-gate }
2167c478bd9Sstevel@tonic-gate }
2177c478bd9Sstevel@tonic-gate return (someerrors);
2187c478bd9Sstevel@tonic-gate }
2197c478bd9Sstevel@tonic-gate
2209fb11590Smike_s boolean
touchfiles(int nfiles,Eptr ** files,int * r_edargc,char *** r_edargv)2219fb11590Smike_s touchfiles(int nfiles, Eptr **files, int *r_edargc, char ***r_edargv)
2227c478bd9Sstevel@tonic-gate {
2237c478bd9Sstevel@tonic-gate char *name;
2249fb11590Smike_s Eptr errorp;
2259fb11590Smike_s int fi;
2269fb11590Smike_s Eptr *erpp;
2277c478bd9Sstevel@tonic-gate int ntrueerrors;
2287c478bd9Sstevel@tonic-gate boolean scribbled;
2297c478bd9Sstevel@tonic-gate int n_pissed_on; /* # of file touched */
2307c478bd9Sstevel@tonic-gate int spread;
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gate FILEITERATE(fi, 1) {
2337c478bd9Sstevel@tonic-gate name = (*files[fi])->error_text[0];
2347c478bd9Sstevel@tonic-gate spread = files[fi+1] - files[fi];
2359fb11590Smike_s (void) fprintf(stdout, terse
2367c478bd9Sstevel@tonic-gate ? "\"%s\" has %d error%s, "
2379fb11590Smike_s : "\nFile \"%s\" has %d error%s.\n",
2389fb11590Smike_s name, spread, plural(spread));
2397c478bd9Sstevel@tonic-gate /*
2407c478bd9Sstevel@tonic-gate * First, iterate through all error messages in this file
2417c478bd9Sstevel@tonic-gate * to see how many of the error messages really will
2427c478bd9Sstevel@tonic-gate * get inserted into the file.
2437c478bd9Sstevel@tonic-gate */
2447c478bd9Sstevel@tonic-gate ntrueerrors = 0;
2457c478bd9Sstevel@tonic-gate EITERATE(erpp, files, fi) {
2467c478bd9Sstevel@tonic-gate errorp = *erpp;
2477c478bd9Sstevel@tonic-gate if (errorp->error_e_class == C_TRUE)
2487c478bd9Sstevel@tonic-gate ntrueerrors++;
2497c478bd9Sstevel@tonic-gate }
2509fb11590Smike_s (void) fprintf(stdout, terse ? "insert %d\n" :
2519fb11590Smike_s "\t%d of these errors can be inserted into the file.\n",
2527c478bd9Sstevel@tonic-gate ntrueerrors);
2537c478bd9Sstevel@tonic-gate
2547c478bd9Sstevel@tonic-gate hackfile(name, files, fi, ntrueerrors);
2557c478bd9Sstevel@tonic-gate }
2567c478bd9Sstevel@tonic-gate scribbled = FALSE;
2577c478bd9Sstevel@tonic-gate n_pissed_on = 0;
2587c478bd9Sstevel@tonic-gate FILEITERATE(fi, 1) {
2597c478bd9Sstevel@tonic-gate scribbled |= touchedfiles[fi];
2607c478bd9Sstevel@tonic-gate n_pissed_on++;
2617c478bd9Sstevel@tonic-gate }
2627c478bd9Sstevel@tonic-gate if (scribbled) {
2637c478bd9Sstevel@tonic-gate /*
2647c478bd9Sstevel@tonic-gate * Construct an execv argument
2657c478bd9Sstevel@tonic-gate */
2667c478bd9Sstevel@tonic-gate execvarg(n_pissed_on, r_edargc, r_edargv);
2677c478bd9Sstevel@tonic-gate return (TRUE);
2687c478bd9Sstevel@tonic-gate } else {
2697c478bd9Sstevel@tonic-gate if (!terse)
2709fb11590Smike_s (void) fprintf(stdout, "You didn't touch any files.\n");
2717c478bd9Sstevel@tonic-gate return (FALSE);
2727c478bd9Sstevel@tonic-gate }
2737c478bd9Sstevel@tonic-gate }
2747c478bd9Sstevel@tonic-gate
2759fb11590Smike_s static void
hackfile(char * name,Eptr ** files,int ix,int nerrors)2769fb11590Smike_s hackfile(char *name, Eptr **files, int ix, int nerrors)
2777c478bd9Sstevel@tonic-gate {
2787c478bd9Sstevel@tonic-gate boolean previewed;
2797c478bd9Sstevel@tonic-gate int errordest; /* where errors go */
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate if (!oktotouch(name)) {
2827c478bd9Sstevel@tonic-gate previewed = FALSE;
2837c478bd9Sstevel@tonic-gate errordest = TOSTDOUT;
2847c478bd9Sstevel@tonic-gate } else {
2859fb11590Smike_s previewed = preview(nerrors, files, ix);
2867c478bd9Sstevel@tonic-gate errordest = settotouch(name);
2877c478bd9Sstevel@tonic-gate }
2887c478bd9Sstevel@tonic-gate
2897c478bd9Sstevel@tonic-gate if (errordest != TOSTDOUT)
2907c478bd9Sstevel@tonic-gate touchedfiles[ix] = TRUE;
2917c478bd9Sstevel@tonic-gate
2927c478bd9Sstevel@tonic-gate if (previewed && (errordest == TOSTDOUT))
2937c478bd9Sstevel@tonic-gate return;
2947c478bd9Sstevel@tonic-gate
2957c478bd9Sstevel@tonic-gate diverterrors(name, errordest, files, ix, previewed, nerrors);
2967c478bd9Sstevel@tonic-gate
2977c478bd9Sstevel@tonic-gate if (errordest == TOTHEFILE) {
2987c478bd9Sstevel@tonic-gate /*
2997c478bd9Sstevel@tonic-gate * overwrite the original file
3007c478bd9Sstevel@tonic-gate */
3017c478bd9Sstevel@tonic-gate writetouched(1);
3027c478bd9Sstevel@tonic-gate }
3037c478bd9Sstevel@tonic-gate }
3047c478bd9Sstevel@tonic-gate
3059fb11590Smike_s static boolean
preview(int nerrors,Eptr ** files,int ix)3069fb11590Smike_s preview(int nerrors, Eptr **files, int ix)
3077c478bd9Sstevel@tonic-gate {
3087c478bd9Sstevel@tonic-gate int back;
3099fb11590Smike_s Eptr *erpp;
3107c478bd9Sstevel@tonic-gate
3117c478bd9Sstevel@tonic-gate if (nerrors <= 0)
3127c478bd9Sstevel@tonic-gate return (FALSE);
3137c478bd9Sstevel@tonic-gate back = FALSE;
3147c478bd9Sstevel@tonic-gate if (query) {
3157c478bd9Sstevel@tonic-gate switch (inquire(terse
3167c478bd9Sstevel@tonic-gate ? "Preview? "
3177c478bd9Sstevel@tonic-gate : "Do you want to preview the errors first? ")) {
3187c478bd9Sstevel@tonic-gate case Q_YES:
3197c478bd9Sstevel@tonic-gate case Q_yes:
3207c478bd9Sstevel@tonic-gate back = TRUE;
3217c478bd9Sstevel@tonic-gate EITERATE(erpp, files, ix) {
3227c478bd9Sstevel@tonic-gate errorprint(stdout, *erpp, TRUE);
3237c478bd9Sstevel@tonic-gate }
3247c478bd9Sstevel@tonic-gate if (!terse)
3259fb11590Smike_s (void) fprintf(stdout, "\n");
3267c478bd9Sstevel@tonic-gate default:
3277c478bd9Sstevel@tonic-gate break;
3287c478bd9Sstevel@tonic-gate }
3297c478bd9Sstevel@tonic-gate }
3307c478bd9Sstevel@tonic-gate return (back);
3317c478bd9Sstevel@tonic-gate }
3327c478bd9Sstevel@tonic-gate
3339fb11590Smike_s static int
settotouch(char * name)3349fb11590Smike_s settotouch(char *name)
3357c478bd9Sstevel@tonic-gate {
3367c478bd9Sstevel@tonic-gate int dest = TOSTDOUT;
3377c478bd9Sstevel@tonic-gate
3387c478bd9Sstevel@tonic-gate if (query) {
3397c478bd9Sstevel@tonic-gate switch (touchstatus = inquire(terse
3407c478bd9Sstevel@tonic-gate ? "Touch? "
3417c478bd9Sstevel@tonic-gate : "Do you want to touch file \"%s\"? ",
3427c478bd9Sstevel@tonic-gate name)) {
3437c478bd9Sstevel@tonic-gate case Q_NO:
3447c478bd9Sstevel@tonic-gate case Q_no:
3457c478bd9Sstevel@tonic-gate return (dest);
3467c478bd9Sstevel@tonic-gate default:
3477c478bd9Sstevel@tonic-gate break;
3487c478bd9Sstevel@tonic-gate }
3497c478bd9Sstevel@tonic-gate }
3507c478bd9Sstevel@tonic-gate
3517c478bd9Sstevel@tonic-gate switch (probethisfile(name)) {
3527c478bd9Sstevel@tonic-gate case F_NOTREAD:
3537c478bd9Sstevel@tonic-gate dest = TOSTDOUT;
3549fb11590Smike_s (void) fprintf(stdout, terse
3557c478bd9Sstevel@tonic-gate ? "\"%s\" unreadable\n"
3567c478bd9Sstevel@tonic-gate : "File \"%s\" is unreadable\n",
3577c478bd9Sstevel@tonic-gate name);
3587c478bd9Sstevel@tonic-gate break;
3597c478bd9Sstevel@tonic-gate case F_NOTWRITE:
3607c478bd9Sstevel@tonic-gate dest = TOSTDOUT;
3619fb11590Smike_s (void) fprintf(stdout, terse
3627c478bd9Sstevel@tonic-gate ? "\"%s\" unwritable\n"
3637c478bd9Sstevel@tonic-gate : "File \"%s\" is unwritable\n",
3647c478bd9Sstevel@tonic-gate name);
3657c478bd9Sstevel@tonic-gate break;
3667c478bd9Sstevel@tonic-gate case F_NOTEXIST:
3677c478bd9Sstevel@tonic-gate dest = TOSTDOUT;
3689fb11590Smike_s (void) fprintf(stdout,
3699fb11590Smike_s terse ? "\"%s\" not found\n" :
3709fb11590Smike_s "Can't find file \"%s\" to insert error "
3719fb11590Smike_s "messages into.\n",
3727c478bd9Sstevel@tonic-gate name);
3737c478bd9Sstevel@tonic-gate break;
3747c478bd9Sstevel@tonic-gate default:
3757c478bd9Sstevel@tonic-gate dest = edit(name) ? TOSTDOUT : TOTHEFILE;
3767c478bd9Sstevel@tonic-gate break;
3777c478bd9Sstevel@tonic-gate }
3787c478bd9Sstevel@tonic-gate return (dest);
3797c478bd9Sstevel@tonic-gate }
3807c478bd9Sstevel@tonic-gate
3819fb11590Smike_s static void
diverterrors(char * name,int dest,Eptr ** files,int ix,boolean previewed,int nterrors)3829fb11590Smike_s diverterrors(char *name, int dest, Eptr **files, int ix,
3839fb11590Smike_s boolean previewed, int nterrors)
3847c478bd9Sstevel@tonic-gate {
3857c478bd9Sstevel@tonic-gate int nerrors;
3869fb11590Smike_s Eptr *erpp;
3879fb11590Smike_s Eptr errorp;
3887c478bd9Sstevel@tonic-gate
3897c478bd9Sstevel@tonic-gate nerrors = files[ix+1] - files[ix];
3907c478bd9Sstevel@tonic-gate
3919fb11590Smike_s if ((nerrors != nterrors) && (!previewed)) {
3929fb11590Smike_s (void) fprintf(stdout, terse
3937c478bd9Sstevel@tonic-gate ? "Uninserted errors\n"
3947c478bd9Sstevel@tonic-gate : ">>Uninserted errors for file \"%s\" follow.\n",
3957c478bd9Sstevel@tonic-gate name);
3967c478bd9Sstevel@tonic-gate }
3977c478bd9Sstevel@tonic-gate
3987c478bd9Sstevel@tonic-gate EITERATE(erpp, files, ix) {
3997c478bd9Sstevel@tonic-gate errorp = *erpp;
4007c478bd9Sstevel@tonic-gate if (errorp->error_e_class != C_TRUE) {
4017c478bd9Sstevel@tonic-gate if (previewed || touchstatus == Q_NO)
4027c478bd9Sstevel@tonic-gate continue;
4037c478bd9Sstevel@tonic-gate errorprint(stdout, errorp, TRUE);
4047c478bd9Sstevel@tonic-gate continue;
4057c478bd9Sstevel@tonic-gate }
4067c478bd9Sstevel@tonic-gate switch (dest) {
4077c478bd9Sstevel@tonic-gate case TOSTDOUT:
4087c478bd9Sstevel@tonic-gate if (previewed || touchstatus == Q_NO)
4097c478bd9Sstevel@tonic-gate continue;
4107c478bd9Sstevel@tonic-gate errorprint(stdout, errorp, TRUE);
4117c478bd9Sstevel@tonic-gate break;
4127c478bd9Sstevel@tonic-gate case TOTHEFILE:
4137c478bd9Sstevel@tonic-gate insert(errorp->error_line);
4147c478bd9Sstevel@tonic-gate text(errorp, FALSE);
4157c478bd9Sstevel@tonic-gate break;
4167c478bd9Sstevel@tonic-gate }
4177c478bd9Sstevel@tonic-gate }
4187c478bd9Sstevel@tonic-gate }
4197c478bd9Sstevel@tonic-gate
4209fb11590Smike_s static int
oktotouch(char * filename)4219fb11590Smike_s oktotouch(char *filename)
4227c478bd9Sstevel@tonic-gate {
4237c478bd9Sstevel@tonic-gate extern char *suffixlist;
4249fb11590Smike_s char *src;
4259fb11590Smike_s char *pat;
4267c478bd9Sstevel@tonic-gate char *osrc;
4277c478bd9Sstevel@tonic-gate
4287c478bd9Sstevel@tonic-gate pat = suffixlist;
4297c478bd9Sstevel@tonic-gate if (pat == 0)
4307c478bd9Sstevel@tonic-gate return (0);
4317c478bd9Sstevel@tonic-gate if (*pat == '*')
4327c478bd9Sstevel@tonic-gate return (1);
4337c478bd9Sstevel@tonic-gate while (*pat++ != '.')
4347c478bd9Sstevel@tonic-gate continue;
4357c478bd9Sstevel@tonic-gate --pat; /* point to the period */
4367c478bd9Sstevel@tonic-gate
4377c478bd9Sstevel@tonic-gate for (src = &filename[strlen(filename)], --src;
4387c478bd9Sstevel@tonic-gate (src > filename) && (*src != '.'); --src)
4397c478bd9Sstevel@tonic-gate continue;
4407c478bd9Sstevel@tonic-gate if (*src != '.')
4417c478bd9Sstevel@tonic-gate return (0);
4427c478bd9Sstevel@tonic-gate
4437c478bd9Sstevel@tonic-gate for (src++, pat++, osrc = src; *src && *pat; src = osrc, pat++) {
4449fb11590Smike_s for (; *src && /* not at end of the source */
4459fb11590Smike_s *pat && /* not off end of pattern */
4469fb11590Smike_s *pat != '.' && /* not off end of sub pattern */
4479fb11590Smike_s *pat != '*' && /* not wild card */
4489fb11590Smike_s *src == *pat; /* and equal... */
4497c478bd9Sstevel@tonic-gate src++, pat++)
4507c478bd9Sstevel@tonic-gate continue;
4517c478bd9Sstevel@tonic-gate if (*src == 0 && (*pat == 0 || *pat == '.' || *pat == '*'))
4527c478bd9Sstevel@tonic-gate return (1);
4537c478bd9Sstevel@tonic-gate if (*src != 0 && *pat == '*')
4547c478bd9Sstevel@tonic-gate return (1);
4557c478bd9Sstevel@tonic-gate while (*pat && *pat != '.')
4567c478bd9Sstevel@tonic-gate pat++;
4577c478bd9Sstevel@tonic-gate if (! *pat)
4587c478bd9Sstevel@tonic-gate return (0);
4597c478bd9Sstevel@tonic-gate }
4607c478bd9Sstevel@tonic-gate return (0);
4617c478bd9Sstevel@tonic-gate }
4627c478bd9Sstevel@tonic-gate /*
4637c478bd9Sstevel@tonic-gate * Construct an execv argument
4647c478bd9Sstevel@tonic-gate * We need 1 argument for the editor's name
4657c478bd9Sstevel@tonic-gate * We need 1 argument for the initial search string
4667c478bd9Sstevel@tonic-gate * We need n_pissed_on arguments for the file names
4677c478bd9Sstevel@tonic-gate * We need 1 argument that is a null for execv.
4687c478bd9Sstevel@tonic-gate * The caller fills in the editor's name.
4697c478bd9Sstevel@tonic-gate * We fill in the initial search string.
4707c478bd9Sstevel@tonic-gate * We fill in the arguments, and the null.
4717c478bd9Sstevel@tonic-gate */
4729fb11590Smike_s static void
execvarg(int n_pissed_on,int * r_argc,char *** r_argv)4739fb11590Smike_s execvarg(int n_pissed_on, int *r_argc, char ***r_argv)
4747c478bd9Sstevel@tonic-gate {
4757c478bd9Sstevel@tonic-gate Eptr p;
4767c478bd9Sstevel@tonic-gate char *sep;
4777c478bd9Sstevel@tonic-gate int fi;
4787c478bd9Sstevel@tonic-gate
4799fb11590Smike_s (*r_argv) = Calloc(n_pissed_on + 3, sizeof (char *));
4807c478bd9Sstevel@tonic-gate (*r_argc) = n_pissed_on + 2;
4817c478bd9Sstevel@tonic-gate (*r_argv)[1] = "+1;/###/";
4827c478bd9Sstevel@tonic-gate n_pissed_on = 2;
4837c478bd9Sstevel@tonic-gate if (!terse) {
4849fb11590Smike_s (void) fprintf(stdout, "You touched file(s):");
4857c478bd9Sstevel@tonic-gate sep = " ";
4867c478bd9Sstevel@tonic-gate }
4877c478bd9Sstevel@tonic-gate FILEITERATE(fi, 1) {
4887c478bd9Sstevel@tonic-gate if (!touchedfiles[fi])
4897c478bd9Sstevel@tonic-gate continue;
4907c478bd9Sstevel@tonic-gate p = *(files[fi]);
4917c478bd9Sstevel@tonic-gate if (!terse) {
4929fb11590Smike_s (void) fprintf(stdout, "%s\"%s\"", sep,
4939fb11590Smike_s p->error_text[0]);
4947c478bd9Sstevel@tonic-gate sep = ", ";
4957c478bd9Sstevel@tonic-gate }
4967c478bd9Sstevel@tonic-gate (*r_argv)[n_pissed_on++] = p->error_text[0];
4977c478bd9Sstevel@tonic-gate }
4987c478bd9Sstevel@tonic-gate if (!terse)
4999fb11590Smike_s (void) fprintf(stdout, "\n");
5007c478bd9Sstevel@tonic-gate (*r_argv)[n_pissed_on] = 0;
5017c478bd9Sstevel@tonic-gate }
5027c478bd9Sstevel@tonic-gate
5037c478bd9Sstevel@tonic-gate FILE *o_touchedfile; /* the old file */
5047c478bd9Sstevel@tonic-gate FILE *n_touchedfile; /* the new file */
5057c478bd9Sstevel@tonic-gate char *o_name;
5067c478bd9Sstevel@tonic-gate char n_name[64];
5077c478bd9Sstevel@tonic-gate char *canon_name = "/tmp/ErrorXXXXXX";
5087c478bd9Sstevel@tonic-gate int o_lineno;
5097c478bd9Sstevel@tonic-gate int n_lineno;
5107c478bd9Sstevel@tonic-gate boolean tempfileopen = FALSE;
5117c478bd9Sstevel@tonic-gate /*
5127c478bd9Sstevel@tonic-gate * open the file; guaranteed to be both readable and writable
5137c478bd9Sstevel@tonic-gate * Well, if it isn't, then return TRUE if something failed
5147c478bd9Sstevel@tonic-gate */
5159fb11590Smike_s static boolean
edit(char * name)5169fb11590Smike_s edit(char *name)
5177c478bd9Sstevel@tonic-gate {
5187c478bd9Sstevel@tonic-gate o_name = name;
5197c478bd9Sstevel@tonic-gate if ((o_touchedfile = fopen(name, "r")) == NULL) {
5209fb11590Smike_s (void) fprintf(stderr,
5219fb11590Smike_s "%s: Can't open file \"%s\" to touch (read).\n",
5227c478bd9Sstevel@tonic-gate processname, name);
5237c478bd9Sstevel@tonic-gate return (TRUE);
5247c478bd9Sstevel@tonic-gate }
5257c478bd9Sstevel@tonic-gate (void) strcpy(n_name, canon_name);
5267c478bd9Sstevel@tonic-gate (void) mktemp(n_name);
5277c478bd9Sstevel@tonic-gate if ((n_touchedfile = fopen(n_name, "w")) == NULL) {
5289fb11590Smike_s (void) fprintf(stderr,
5299fb11590Smike_s "%s: Can't open file \"%s\" to touch (write).\n",
5307c478bd9Sstevel@tonic-gate processname, name);
5317c478bd9Sstevel@tonic-gate return (TRUE);
5327c478bd9Sstevel@tonic-gate }
5337c478bd9Sstevel@tonic-gate tempfileopen = TRUE;
5347c478bd9Sstevel@tonic-gate n_lineno = 0;
5357c478bd9Sstevel@tonic-gate o_lineno = 0;
5367c478bd9Sstevel@tonic-gate return (FALSE);
5377c478bd9Sstevel@tonic-gate }
5387c478bd9Sstevel@tonic-gate /*
5397c478bd9Sstevel@tonic-gate * Position to the line (before, after) the line given by place
5407c478bd9Sstevel@tonic-gate */
5417c478bd9Sstevel@tonic-gate char edbuf[BUFSIZ];
5429fb11590Smike_s
5439fb11590Smike_s static void
insert(int place)5449fb11590Smike_s insert(int place)
5457c478bd9Sstevel@tonic-gate {
5467c478bd9Sstevel@tonic-gate --place; /* always insert messages before the offending line */
5477c478bd9Sstevel@tonic-gate for (; o_lineno < place; o_lineno++, n_lineno++) {
5487c478bd9Sstevel@tonic-gate if (fgets(edbuf, BUFSIZ, o_touchedfile) == NULL)
5497c478bd9Sstevel@tonic-gate return;
5509fb11590Smike_s (void) fputs(edbuf, n_touchedfile);
5517c478bd9Sstevel@tonic-gate }
5527c478bd9Sstevel@tonic-gate }
5537c478bd9Sstevel@tonic-gate
5549fb11590Smike_s static void
text(Eptr p,boolean use_all)5559fb11590Smike_s text(Eptr p, boolean use_all)
5567c478bd9Sstevel@tonic-gate {
5577c478bd9Sstevel@tonic-gate int offset = use_all ? 0 : 2;
5587c478bd9Sstevel@tonic-gate
5599fb11590Smike_s (void) fputs(lang_table[p->error_language].lang_incomment,
5609fb11590Smike_s n_touchedfile);
5619fb11590Smike_s (void) fprintf(n_touchedfile, "%d [%s] ",
5627c478bd9Sstevel@tonic-gate p->error_line,
5637c478bd9Sstevel@tonic-gate lang_table[p->error_language].lang_name);
5647c478bd9Sstevel@tonic-gate wordvprint(n_touchedfile, p->error_lgtext-offset, p->error_text+offset);
5659fb11590Smike_s (void) fputs(lang_table[p->error_language].lang_outcomment,
5669fb11590Smike_s n_touchedfile);
5677c478bd9Sstevel@tonic-gate n_lineno++;
5687c478bd9Sstevel@tonic-gate }
5697c478bd9Sstevel@tonic-gate
5707c478bd9Sstevel@tonic-gate /*
5717c478bd9Sstevel@tonic-gate * write the touched file to its temporary copy,
5727c478bd9Sstevel@tonic-gate * then bring the temporary in over the local file
5737c478bd9Sstevel@tonic-gate */
5749fb11590Smike_s static void
writetouched(int overwrite)5759fb11590Smike_s writetouched(int overwrite)
5767c478bd9Sstevel@tonic-gate {
5779fb11590Smike_s int nread;
5789fb11590Smike_s FILE *localfile;
5799fb11590Smike_s FILE *tmpfile;
5807c478bd9Sstevel@tonic-gate int botch;
5817c478bd9Sstevel@tonic-gate int oktorm;
5827c478bd9Sstevel@tonic-gate
5837c478bd9Sstevel@tonic-gate botch = 0;
5847c478bd9Sstevel@tonic-gate oktorm = 1;
5859fb11590Smike_s while ((nread = fread(edbuf, 1, sizeof (edbuf),
58617a5fa85SToomas Soome o_touchedfile)) != 0) {
5877c478bd9Sstevel@tonic-gate if (nread != fwrite(edbuf, 1, nread, n_touchedfile)) {
5887c478bd9Sstevel@tonic-gate /*
5897c478bd9Sstevel@tonic-gate * Catastrophe in temporary area: file system full?
5907c478bd9Sstevel@tonic-gate */
5917c478bd9Sstevel@tonic-gate botch = 1;
5929fb11590Smike_s (void) fprintf(stderr,
5937c478bd9Sstevel@tonic-gate "%s: write failure: No errors inserted in \"%s\"\n",
5947c478bd9Sstevel@tonic-gate processname, o_name);
5957c478bd9Sstevel@tonic-gate }
5967c478bd9Sstevel@tonic-gate }
5979fb11590Smike_s (void) fclose(n_touchedfile);
5989fb11590Smike_s (void) fclose(o_touchedfile);
5997c478bd9Sstevel@tonic-gate /*
6007c478bd9Sstevel@tonic-gate * Now, copy the temp file back over the original
6017c478bd9Sstevel@tonic-gate * file, thus preserving links, etc
6027c478bd9Sstevel@tonic-gate */
6037c478bd9Sstevel@tonic-gate if (botch == 0 && overwrite) {
6047c478bd9Sstevel@tonic-gate botch = 0;
6057c478bd9Sstevel@tonic-gate localfile = NULL;
6067c478bd9Sstevel@tonic-gate tmpfile = NULL;
6077c478bd9Sstevel@tonic-gate if ((localfile = fopen(o_name, "w")) == NULL) {
6089fb11590Smike_s (void) fprintf(stderr,
6097c478bd9Sstevel@tonic-gate "%s: Can't open file \"%s\" to overwrite.\n",
6107c478bd9Sstevel@tonic-gate processname, o_name);
6117c478bd9Sstevel@tonic-gate botch++;
6127c478bd9Sstevel@tonic-gate }
6137c478bd9Sstevel@tonic-gate if ((tmpfile = fopen(n_name, "r")) == NULL) {
6149fb11590Smike_s (void) fprintf(stderr,
6159fb11590Smike_s "%s: Can't open file \"%s\" to read.\n",
6167c478bd9Sstevel@tonic-gate processname, n_name);
6177c478bd9Sstevel@tonic-gate botch++;
6187c478bd9Sstevel@tonic-gate }
6197c478bd9Sstevel@tonic-gate if (!botch)
6207c478bd9Sstevel@tonic-gate oktorm = mustoverwrite(localfile, tmpfile);
6217c478bd9Sstevel@tonic-gate if (localfile != NULL)
6229fb11590Smike_s (void) fclose(localfile);
6237c478bd9Sstevel@tonic-gate if (tmpfile != NULL)
6249fb11590Smike_s (void) fclose(tmpfile);
6257c478bd9Sstevel@tonic-gate }
6267c478bd9Sstevel@tonic-gate if (oktorm == 0) {
6279fb11590Smike_s (void) fprintf(stderr,
6289fb11590Smike_s "%s: Catastrophe: A copy of \"%s: was saved in \"%s\"\n",
6297c478bd9Sstevel@tonic-gate processname, o_name, n_name);
6307c478bd9Sstevel@tonic-gate exit(1);
6317c478bd9Sstevel@tonic-gate }
6327c478bd9Sstevel@tonic-gate /*
6337c478bd9Sstevel@tonic-gate * Kiss the temp file good bye
6347c478bd9Sstevel@tonic-gate */
6359fb11590Smike_s (void) unlink(n_name);
6367c478bd9Sstevel@tonic-gate tempfileopen = FALSE;
6377c478bd9Sstevel@tonic-gate }
6387c478bd9Sstevel@tonic-gate /*
6397c478bd9Sstevel@tonic-gate * return 1 if the tmpfile can be removed after writing it out
6407c478bd9Sstevel@tonic-gate */
6419fb11590Smike_s static int
mustoverwrite(FILE * preciousfile,FILE * tmpfile)6429fb11590Smike_s mustoverwrite(FILE *preciousfile, FILE *tmpfile)
6437c478bd9Sstevel@tonic-gate {
6447c478bd9Sstevel@tonic-gate int nread;
6457c478bd9Sstevel@tonic-gate
64617a5fa85SToomas Soome while ((nread = fread(edbuf, 1, sizeof (edbuf), tmpfile)) != 0) {
6477c478bd9Sstevel@tonic-gate if (mustwrite(edbuf, nread, preciousfile) == 0)
6487c478bd9Sstevel@tonic-gate return (0);
6497c478bd9Sstevel@tonic-gate }
6507c478bd9Sstevel@tonic-gate return (1);
6517c478bd9Sstevel@tonic-gate }
6527c478bd9Sstevel@tonic-gate /*
6537c478bd9Sstevel@tonic-gate * return 0 on catastrophe
6547c478bd9Sstevel@tonic-gate */
6559fb11590Smike_s static int
mustwrite(char * base,int n,FILE * preciousfile)6569fb11590Smike_s mustwrite(char *base, int n, FILE *preciousfile)
6577c478bd9Sstevel@tonic-gate {
6587c478bd9Sstevel@tonic-gate int nwrote;
6597c478bd9Sstevel@tonic-gate
6607c478bd9Sstevel@tonic-gate if (n <= 0)
6617c478bd9Sstevel@tonic-gate return (1);
6627c478bd9Sstevel@tonic-gate nwrote = fwrite(base, 1, n, preciousfile);
6637c478bd9Sstevel@tonic-gate if (nwrote == n)
6647c478bd9Sstevel@tonic-gate return (1);
6657c478bd9Sstevel@tonic-gate perror(processname);
6667c478bd9Sstevel@tonic-gate switch (inquire(terse
6677c478bd9Sstevel@tonic-gate ? "Botch overwriting: retry? "
6687c478bd9Sstevel@tonic-gate : "Botch overwriting the source file: retry? ")) {
6697c478bd9Sstevel@tonic-gate case Q_YES:
6707c478bd9Sstevel@tonic-gate case Q_yes:
6719fb11590Smike_s (void) mustwrite(base + nwrote, n - nwrote, preciousfile);
6727c478bd9Sstevel@tonic-gate return (1);
6737c478bd9Sstevel@tonic-gate case Q_NO:
6747c478bd9Sstevel@tonic-gate case Q_no:
6757c478bd9Sstevel@tonic-gate switch (inquire("Are you sure? ")) {
6767c478bd9Sstevel@tonic-gate case Q_YES:
6777c478bd9Sstevel@tonic-gate case Q_yes:
6787c478bd9Sstevel@tonic-gate return (0);
6797c478bd9Sstevel@tonic-gate case Q_NO:
6807c478bd9Sstevel@tonic-gate case Q_no:
681698f4ab6SToomas Soome default:
6829fb11590Smike_s (void) mustwrite(base + nwrote, n - nwrote,
6839fb11590Smike_s preciousfile);
6847c478bd9Sstevel@tonic-gate return (1);
6857c478bd9Sstevel@tonic-gate }
6867c478bd9Sstevel@tonic-gate default:
6877c478bd9Sstevel@tonic-gate return (0);
6887c478bd9Sstevel@tonic-gate }
6897c478bd9Sstevel@tonic-gate }
6907c478bd9Sstevel@tonic-gate
6919fb11590Smike_s /* ARGSUSED */
6929fb11590Smike_s void
onintr(int sig)6939fb11590Smike_s onintr(int sig)
6947c478bd9Sstevel@tonic-gate {
6957c478bd9Sstevel@tonic-gate switch (inquire(terse
6967c478bd9Sstevel@tonic-gate ? "\nContinue? "
6977c478bd9Sstevel@tonic-gate : "\nInterrupt: Do you want to continue? ")) {
6987c478bd9Sstevel@tonic-gate case Q_YES:
6997c478bd9Sstevel@tonic-gate case Q_yes:
7009fb11590Smike_s (void) signal(SIGINT, onintr);
7017c478bd9Sstevel@tonic-gate return;
7027c478bd9Sstevel@tonic-gate default:
7037c478bd9Sstevel@tonic-gate if (tempfileopen) {
7047c478bd9Sstevel@tonic-gate /*
7057c478bd9Sstevel@tonic-gate * Don't overwrite the original file!
7067c478bd9Sstevel@tonic-gate */
7077c478bd9Sstevel@tonic-gate writetouched(0);
7087c478bd9Sstevel@tonic-gate }
7097c478bd9Sstevel@tonic-gate exit(1);
7107c478bd9Sstevel@tonic-gate }
7117c478bd9Sstevel@tonic-gate /*NOTREACHED*/
7127c478bd9Sstevel@tonic-gate }
7137c478bd9Sstevel@tonic-gate
7149fb11590Smike_s static void
errorprint(FILE * place,Eptr errorp,boolean print_all)7159fb11590Smike_s errorprint(FILE *place, Eptr errorp, boolean print_all)
7167c478bd9Sstevel@tonic-gate {
7177c478bd9Sstevel@tonic-gate int offset = print_all ? 0 : 2;
7187c478bd9Sstevel@tonic-gate
7197c478bd9Sstevel@tonic-gate if (errorp->error_e_class == C_IGNORE)
7207c478bd9Sstevel@tonic-gate return;
7219fb11590Smike_s (void) fprintf(place, "[%s] ",
7229fb11590Smike_s lang_table[errorp->error_language].lang_name);
7239fb11590Smike_s wordvprint(place, errorp->error_lgtext-offset,
7249fb11590Smike_s errorp->error_text+offset);
7259fb11590Smike_s (void) putc('\n', place);
7267c478bd9Sstevel@tonic-gate }
7277c478bd9Sstevel@tonic-gate
7289fb11590Smike_s /*PRINTFLIKE1*/
7299fb11590Smike_s int
inquire(char * format,...)7309fb11590Smike_s inquire(char *format, ...)
7317c478bd9Sstevel@tonic-gate {
7327c478bd9Sstevel@tonic-gate char buffer[128];
7339fb11590Smike_s va_list args;
7347c478bd9Sstevel@tonic-gate
7357c478bd9Sstevel@tonic-gate if (queryfile == NULL)
7367c478bd9Sstevel@tonic-gate return (0);
7377c478bd9Sstevel@tonic-gate for (;;) {
7387c478bd9Sstevel@tonic-gate do {
7399fb11590Smike_s va_start(args, format);
7409fb11590Smike_s (void) fflush(stdout);
7419fb11590Smike_s (void) vfprintf(stderr, format, args);
7429fb11590Smike_s (void) fflush(stderr);
7439fb11590Smike_s va_end(args);
7447c478bd9Sstevel@tonic-gate } while (fgets(buffer, 127, queryfile) == NULL);
7457c478bd9Sstevel@tonic-gate switch (buffer[0]) {
7467c478bd9Sstevel@tonic-gate case 'Y': return (Q_YES);
7477c478bd9Sstevel@tonic-gate case 'y': return (Q_yes);
7487c478bd9Sstevel@tonic-gate case 'N': return (Q_NO);
7497c478bd9Sstevel@tonic-gate case 'n': return (Q_no);
7509fb11590Smike_s default: (void) fprintf(stderr, "Yes or No only!\n");
7517c478bd9Sstevel@tonic-gate }
7527c478bd9Sstevel@tonic-gate }
7537c478bd9Sstevel@tonic-gate }
7547c478bd9Sstevel@tonic-gate
7559fb11590Smike_s int
probethisfile(char * name)7569fb11590Smike_s probethisfile(char *name)
7577c478bd9Sstevel@tonic-gate {
7587c478bd9Sstevel@tonic-gate struct stat statbuf;
7597c478bd9Sstevel@tonic-gate if (stat(name, &statbuf) < 0)
7607c478bd9Sstevel@tonic-gate return (F_NOTEXIST);
7617c478bd9Sstevel@tonic-gate if ((statbuf.st_mode & S_IREAD) == 0)
7627c478bd9Sstevel@tonic-gate return (F_NOTREAD);
7637c478bd9Sstevel@tonic-gate if ((statbuf.st_mode & S_IWRITE) == 0)
7647c478bd9Sstevel@tonic-gate return (F_NOTWRITE);
7657c478bd9Sstevel@tonic-gate return (F_TOUCHIT);
7667c478bd9Sstevel@tonic-gate }
767