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
143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h>
15822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#ifdef HAVE_TERMIOS_H
16822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#include <termios.h>
17822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#endif
18822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#ifdef HAVE_UNISTD_H
19822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#include <unistd.h>
20822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#endif
21f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include "com_err.h"
223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "error_table.h"
233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "internal.h"
243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic void
2691835c151fd48fd03bfe74133b8214486af18c12Theodore Ts'odefault_com_err_proc (const char *whoami, errcode_t code, const
2791835c151fd48fd03bfe74133b8214486af18c12Theodore Ts'o		      char *fmt, va_list args)
282540bb79b728cbfb88ed80e8ca2c2d8c0edc129bTheodore Ts'o	COM_ERR_ATTR((format(printf, 3, 0)));
292540bb79b728cbfb88ed80e8ca2c2d8c0edc129bTheodore Ts'o
302540bb79b728cbfb88ed80e8ca2c2d8c0edc129bTheodore Ts'ostatic void
312540bb79b728cbfb88ed80e8ca2c2d8c0edc129bTheodore Ts'odefault_com_err_proc (const char *whoami, errcode_t code, const
322540bb79b728cbfb88ed80e8ca2c2d8c0edc129bTheodore Ts'o		      char *fmt, va_list args)
333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
34822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o    int do_cr = 1, fd = fileno(stderr);
35822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o
363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    if (whoami) {
373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	fputs(whoami, stderr);
383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	fputs(": ", stderr);
393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    }
403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    if (code) {
413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	fputs(error_message(code), stderr);
423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	fputs(" ", stderr);
433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    }
443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    if (fmt) {
453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o        vfprintf (stderr, fmt, args);
463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    }
47822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o    if (!isatty(fd))
48822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o	do_cr = 0;
49822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#ifdef HAVE_TERMIOS_H
50822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o    else {
51822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o	struct termios t;
52822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o
53822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o	if ((tcgetattr(fd, &t)) == 0 &&
54822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o	    (t.c_oflag & OPOST) && (t.c_oflag & ONLCR))
55822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o	do_cr = 0;
56822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o    }
57822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o#endif
58822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o    if (do_cr)
59822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o	fputc('\r', stderr);
60822c10e84e5f57394bcad921adc560f5b032c03eTheodore Ts'o    fputc('\n', stderr);
613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    fflush(stderr);
623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
64f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'otypedef void (*errf) (const char *, errcode_t, const char *, va_list);
653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oerrf com_err_hook = default_com_err_proc;
673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
68f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'ovoid com_err_va (const char *whoami, errcode_t code, const char *fmt,
69f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		 va_list args)
703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    (*com_err_hook) (whoami, code, fmt, args);
723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid com_err (const char *whoami,
75f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	      errcode_t code,
763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	      const char *fmt, ...)
773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    va_list pvar;
793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    if (!com_err_hook)
813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	com_err_hook = default_com_err_proc;
823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    va_start(pvar, fmt);
833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    com_err_va (whoami, code, fmt, pvar);
843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    va_end(pvar);
853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
87e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrf set_com_err_hook(errf new_proc)
883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    errf x = com_err_hook;
903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    if (new_proc)
923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	com_err_hook = new_proc;
933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    else
943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	com_err_hook = default_com_err_proc;
953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    return x;
973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
99e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrf reset_com_err_hook(void) {
1003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    errf x = com_err_hook;
1013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    com_err_hook = default_com_err_proc;
1023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    return x;
1033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
104