diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 | 
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 | 
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /maildir/maildiropen.c | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2 | |
Initial checkin
Imported from subversion report, converted to git. Updated all paths in
scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'maildir/maildiropen.c')
| -rw-r--r-- | maildir/maildiropen.c | 140 | 
1 files changed, 140 insertions, 0 deletions
| diff --git a/maildir/maildiropen.c b/maildir/maildiropen.c new file mode 100644 index 0000000..2542873 --- /dev/null +++ b/maildir/maildiropen.c @@ -0,0 +1,140 @@ +/* +** Copyright 2000 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include	<sys/types.h> +#include	<sys/stat.h> +#include	<string.h> +#include	<stdlib.h> +#include	<time.h> +#if	HAVE_UNISTD_H +#include	<unistd.h> +#endif +#include	<stdio.h> +#include	<ctype.h> +#include	<errno.h> +#include	<fcntl.h> + +#include	"maildirmisc.h" + + +char *maildir_getlink(const char *filename) +{ +#if     HAVE_READLINK +size_t	bufsiz; +char	*buf; + +	bufsiz=0; +	buf=0; + +	for (;;) +	{ +	int	n; + +		if (buf)	free(buf); +		bufsiz += 256; +		if ((buf=malloc(bufsiz)) == 0) +		{ +			perror("malloc"); +			return (0); +		} +		if ((n=readlink(filename, buf, bufsiz)) < 0) +		{ +			free(buf); +			return (0); +		} +		if (n < bufsiz) +		{ +			buf[n]=0; +			break; +		} +	} +	return (buf); +#else +	return (0); +#endif +} + +int maildir_semisafeopen(const char *path, int mode, int perm) +{ + +#if	HAVE_READLINK + +char	*l=maildir_getlink(path); + +	if (l) +	{ +	int	f; + +		if (*l != '/') +		{ +		char	*q=malloc(strlen(path)+strlen(l)+2); +		char	*s; + +			if (!q) +			{ +				free(l); +				return (-1); +			} + +			strcpy(q, path); +			if ((s=strchr(q, '/')) != 0) +				s[1]=0; +			else	*q=0; +			strcat(q, l); +			free(l); +			l=q; +		} + +		f=maildir_safeopen(l, mode, perm); + +		free(l); +		return (f); +	} +#endif + +	return (maildir_safeopen(path, mode, perm)); +} +		 +int maildir_safeopen(const char *path, int mode, int perm) +{ +	struct	stat	stat1; + +	return maildir_safeopen_stat(path, mode, perm, &stat1); +} + +int maildir_safeopen_stat(const char *path, int mode, int perm, +			  struct stat *stat1) +{ +	struct	stat	stat2; + +	int	fd=open(path, mode +#ifdef	O_NONBLOCK +			| O_NONBLOCK +#else +			| O_NDELAY +#endif +			, perm); + +	if (fd < 0)	return (fd); +	if (fcntl(fd, F_SETFL, (mode & O_APPEND)) || fstat(fd, stat1) +	    || lstat(path, &stat2)) +	{ +		close(fd); +		return (-1); +	} + +	if (stat1->st_dev != stat2.st_dev || stat1->st_ino != stat2.st_ino) +	{ +		close(fd); +		errno=ENOENT; +		return (-1); +	} + +	return (fd); +} | 
