Back to index

courier  0.68.2
maildiropen.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 2000 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 #if HAVE_CONFIG_H
00007 #include "config.h"
00008 #endif
00009 
00010 #include      <sys/types.h>
00011 #include      <sys/stat.h>
00012 #include      <string.h>
00013 #include      <stdlib.h>
00014 #include      <time.h>
00015 #if    HAVE_UNISTD_H
00016 #include      <unistd.h>
00017 #endif
00018 #include      <stdio.h>
00019 #include      <ctype.h>
00020 #include      <errno.h>
00021 #include      <fcntl.h>
00022 
00023 #include      "maildirmisc.h"
00024 
00025 
00026 char *maildir_getlink(const char *filename)
00027 {
00028 #if     HAVE_READLINK
00029 size_t bufsiz;
00030 char   *buf;
00031 
00032        bufsiz=0;
00033        buf=0;
00034 
00035        for (;;)
00036        {
00037        int    n;
00038 
00039               if (buf)      free(buf);
00040               bufsiz += 256;
00041               if ((buf=malloc(bufsiz)) == 0)
00042               {
00043                      perror("malloc");
00044                      return (0);
00045               }
00046               if ((n=readlink(filename, buf, bufsiz)) < 0)
00047               {
00048                      free(buf);
00049                      return (0);
00050               }
00051               if (n < bufsiz)
00052               {
00053                      buf[n]=0;
00054                      break;
00055               }
00056        }
00057        return (buf);
00058 #else
00059        return (0);
00060 #endif
00061 }
00062 
00063 int maildir_semisafeopen(const char *path, int mode, int perm)
00064 {
00065 
00066 #if    HAVE_READLINK
00067 
00068 char   *l=maildir_getlink(path);
00069 
00070        if (l)
00071        {
00072        int    f;
00073 
00074               if (*l != '/')
00075               {
00076               char   *q=malloc(strlen(path)+strlen(l)+2);
00077               char   *s;
00078 
00079                      if (!q)
00080                      {
00081                             free(l);
00082                             return (-1);
00083                      }
00084 
00085                      strcpy(q, path);
00086                      if ((s=strchr(q, '/')) != 0)
00087                             s[1]=0;
00088                      else   *q=0;
00089                      strcat(q, l);
00090                      free(l);
00091                      l=q;
00092               }
00093 
00094               f=maildir_safeopen(l, mode, perm);
00095 
00096               free(l);
00097               return (f);
00098        }
00099 #endif
00100 
00101        return (maildir_safeopen(path, mode, perm));
00102 }
00103               
00104 int maildir_safeopen(const char *path, int mode, int perm)
00105 {
00106        struct stat   stat1;
00107 
00108        return maildir_safeopen_stat(path, mode, perm, &stat1);
00109 }
00110 
00111 int maildir_safeopen_stat(const char *path, int mode, int perm,
00112                        struct stat *stat1)
00113 {
00114        struct stat   stat2;
00115 
00116        int    fd=open(path, mode
00117 #ifdef O_NONBLOCK
00118                      | O_NONBLOCK
00119 #else
00120                      | O_NDELAY
00121 #endif
00122                      , perm);
00123 
00124        if (fd < 0)   return (fd);
00125        if (fcntl(fd, F_SETFL, (mode & O_APPEND)) || fstat(fd, stat1)
00126            || lstat(path, &stat2))
00127        {
00128               close(fd);
00129               return (-1);
00130        }
00131 
00132        if (stat1->st_dev != stat2.st_dev || stat1->st_ino != stat2.st_ino)
00133        {
00134               close(fd);
00135               errno=ENOENT;
00136               return (-1);
00137        }
00138 
00139        return (fd);
00140 }