xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/sane_link.c (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
1 /*	$NetBSD: sane_link.c,v 1.1.1.1 2009/06/23 10:09:00 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	sane_link 3
6 /* SUMMARY
7 /*	sanitize link() error returns
8 /* SYNOPSIS
9 /*	#include <sane_fsops.h>
10 /*
11 /*	int	sane_link(from, to)
12 /*	const char *from;
13 /*	const char *to;
14 /* DESCRIPTION
15 /*	sane_link() implements the link(2) system call, and works
16 /*	around some errors that are possible with NFS file systems.
17 /* LICENSE
18 /* .ad
19 /* .fi
20 /*	The Secure Mailer license must be distributed with this software.
21 /* AUTHOR(S)
22 /*	Wietse Venema
23 /*	IBM T.J. Watson Research
24 /*	P.O. Box 704
25 /*	Yorktown Heights, NY 10598, USA
26 /*--*/
27 
28 /* System library. */
29 
30 #include "sys_defs.h"
31 #include <sys/stat.h>
32 #include <errno.h>
33 #include <unistd.h>
34 
35 /* Utility library. */
36 
37 #include "msg.h"
38 #include "sane_fsops.h"
39 
40 /* sane_link - sanitize link() error returns */
41 
42 int     sane_link(const char *from, const char *to)
43 {
44     const char *myname = "sane_link";
45     int     saved_errno;
46     struct stat from_st;
47     struct stat to_st;
48 
49     /*
50      * Normal case: link() succeeds.
51      */
52     if (link(from, to) >= 0)
53 	return (0);
54 
55     /*
56      * Woops. Save errno, and see if the error is an NFS artefact. If it is,
57      * pretend the error never happened.
58      */
59     saved_errno = errno;
60     if (stat(from, &from_st) >= 0 && stat(to, &to_st) >= 0
61 	&& from_st.st_dev == to_st.st_dev
62 	&& from_st.st_ino == to_st.st_ino) {
63 	msg_info("%s(%s,%s): worked around spurious NFS error",
64 		 myname, from, to);
65 	return (0);
66     }
67 
68     /*
69      * Nope, it didn't. Restore errno and report the error.
70      */
71     errno = saved_errno;
72     return (-1);
73 }
74