1/*++
2/* NAME
3/*	warn_stat 3
4/* SUMMARY
5/*	baby-sit stat() error returns
6/* SYNOPSIS
7/*	#include <warn_stat.h>
8/*
9/*	int     warn_stat(path, st)
10/*	const char *path;
11/*	struct stat *st;
12/*
13/*	int     warn_lstat(path, st)
14/*	const char *path;
15/*	struct stat *st;
16/*
17/*	int     warn_fstat(fd, st)
18/*	int     fd;
19/*	struct stat *st;
20/* DESCRIPTION
21/*	warn_stat(), warn_fstat() and warn_lstat() wrap the stat(),
22/*	fstat() and lstat() system calls with code that logs a
23/*	diagnosis for common error cases.
24/* LICENSE
25/* .ad
26/* .fi
27/*	The Secure Mailer license must be distributed with this software.
28/* AUTHOR(S)
29/*	Wietse Venema
30/*	IBM T.J. Watson Research
31/*	P.O. Box 704
32/*	Yorktown Heights, NY 10598, USA
33/*--*/
34
35/* System library. */
36
37#include <sys_defs.h>
38#include <sys/stat.h>
39#include <errno.h>
40
41/* Utility library. */
42
43#include <msg.h>
44#define WARN_STAT_INTERNAL
45#include <warn_stat.h>
46
47/* diagnose_stat - log stat warning */
48
49static void diagnose_stat(void)
50{
51    struct stat st;
52
53    /*
54     * When *stat() fails with EOVERFLOW, and the interface uses 32-bit data
55     * types, suggest that the program be recompiled with larger data types.
56     */
57#ifdef EOVERFLOW
58    if (errno == EOVERFLOW && sizeof(st.st_size) == 4) {
59	msg_warn("this program was built for 32-bit file handles, "
60		 "but some number does not fit in 32 bits");
61	msg_warn("possible solution: recompile in 64-bit mode, or "
62		 "recompile in 32-bit mode with 'large file' support");
63    }
64#endif
65}
66
67/* warn_stat - stat with warning */
68
69int     warn_stat(const char *path, struct stat * st)
70{
71    int     ret;
72
73    ret = stat(path, st);
74    if (ret < 0)
75	diagnose_stat();
76    return (ret);
77}
78
79/* warn_lstat - lstat with warning */
80
81int     warn_lstat(const char *path, struct stat * st)
82{
83    int     ret;
84
85    ret = lstat(path, st);
86    if (ret < 0)
87	diagnose_stat();
88    return (ret);
89}
90
91/* warn_fstat - fstat with warning */
92
93int     warn_fstat(int fd, struct stat * st)
94{
95    int     ret;
96
97    ret = fstat(fd, st);
98    if (ret < 0)
99	diagnose_stat();
100    return (ret);
101}
102