13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Copyright 1987, 1988 by MIT Student Information Processing Board.
3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
406cefee50dc681838454fcd079ba5b2760969f1bTheodore Ts'o * Permission to use, copy, modify, and distribute this software and
506cefee50dc681838454fcd079ba5b2760969f1bTheodore Ts'o * its documentation for any purpose is hereby granted, provided that
606cefee50dc681838454fcd079ba5b2760969f1bTheodore Ts'o * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
706cefee50dc681838454fcd079ba5b2760969f1bTheodore Ts'o * advertising or publicity pertaining to distribution of the software
806cefee50dc681838454fcd079ba5b2760969f1bTheodore Ts'o * without specific, written prior permission.  M.I.T. and the
906cefee50dc681838454fcd079ba5b2760969f1bTheodore Ts'o * M.I.T. S.I.P.B. make no representations about the suitability of
1006cefee50dc681838454fcd079ba5b2760969f1bTheodore Ts'o * this software for any purpose.  It is provided "as is" without
1106cefee50dc681838454fcd079ba5b2760969f1bTheodore Ts'o * express or implied warranty.
123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
14d1154eb460efe588eaed3d439c1caaca149fa362Theodore Ts'o#include "config.h"
153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h>
16822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#ifdef HAVE_TERMIOS_H
17822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#include <termios.h>
18822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#endif
19822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#ifdef HAVE_UNISTD_H
20822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#include <unistd.h>
21822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#endif
22f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include "com_err.h"
233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "error_table.h"
243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "internal.h"
253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic void
2791835c151fd48fd03bfe74133b8214486af18c12Theodore Ts'odefault_com_err_proc (const char *whoami, errcode_t code, const
2891835c151fd48fd03bfe74133b8214486af18c12Theodore Ts'o		      char *fmt, va_list args)
292540bb79b728cbfb88ed80e8ca2c2d8c0edc129bTheodore Ts'o	COM_ERR_ATTR((format(printf, 3, 0)));
302540bb79b728cbfb88ed80e8ca2c2d8c0edc129bTheodore Ts'o
312540bb79b728cbfb88ed80e8ca2c2d8c0edc129bTheodore Ts'ostatic void
322540bb79b728cbfb88ed80e8ca2c2d8c0edc129bTheodore Ts'odefault_com_err_proc (const char *whoami, errcode_t code, const
332540bb79b728cbfb88ed80e8ca2c2d8c0edc129bTheodore Ts'o		      char *fmt, va_list args)
343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
35822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o    int do_cr = 1, fd = fileno(stderr);
36822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o
373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    if (whoami) {
383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	fputs(whoami, stderr);
393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	fputs(": ", stderr);
403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    }
413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    if (code) {
423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	fputs(error_message(code), stderr);
433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	fputs(" ", stderr);
443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    }
453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    if (fmt) {
463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o        vfprintf (stderr, fmt, args);
473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    }
48822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o    if (!isatty(fd))
49822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o	do_cr = 0;
50822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#ifdef HAVE_TERMIOS_H
51822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o    else {
52822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o	struct termios t;
53822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o
54822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o	if ((tcgetattr(fd, &t)) == 0 &&
55822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o	    (t.c_oflag & OPOST) && (t.c_oflag & ONLCR))
56822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o	do_cr = 0;
57822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o    }
58822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#endif
59822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o    if (do_cr)
60822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o	fputc('\r', stderr);
61822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o    fputc('\n', stderr);
623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    fflush(stderr);
633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
65f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'otypedef void (*errf) (const char *, errcode_t, const char *, va_list);
663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oerrf com_err_hook = default_com_err_proc;
683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
69f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'ovoid com_err_va (const char *whoami, errcode_t code, const char *fmt,
70f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		 va_list args)
713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    (*com_err_hook) (whoami, code, fmt, args);
733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid com_err (const char *whoami,
76f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	      errcode_t code,
773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	      const char *fmt, ...)
783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    va_list pvar;
803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    if (!com_err_hook)
823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	com_err_hook = default_com_err_proc;
833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    va_start(pvar, fmt);
843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    com_err_va (whoami, code, fmt, pvar);
853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    va_end(pvar);
863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
88f404167dda29a59d2be2882328aeb074b9899669Theodore Ts'oerrf set_com_err_hook(errf new_proc)
893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    errf x = com_err_hook;
913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    if (new_proc)
933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	com_err_hook = new_proc;
943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    else
953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	com_err_hook = default_com_err_proc;
963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    return x;
983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
993839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
100f404167dda29a59d2be2882328aeb074b9899669Theodore Ts'oerrf reset_com_err_hook(void) {
1013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    errf x = com_err_hook;
1023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    com_err_hook = default_com_err_proc;
1033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    return x;
1043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
105