maildiropen.c
上传用户:s81996212
上传日期:2007-01-04
资源大小:722k
文件大小:2k
源码类别:

WEB邮件程序

开发平台:

C/C++

  1. /*
  2. ** Copyright 2000 Double Precision, Inc.
  3. ** See COPYING for distribution information.
  4. */
  5. #if HAVE_CONFIG_H
  6. #include "config.h"
  7. #endif
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <time.h>
  13. #if HAVE_UNISTD_H
  14. #include <unistd.h>
  15. #endif
  16. #include <stdio.h>
  17. #include <ctype.h>
  18. #include <errno.h>
  19. #include <fcntl.h>
  20. #include "maildirmisc.h"
  21. static const char rcsid[]="$Id: maildiropen.c,v 1.6 2000/02/25 00:24:45 mrsam Exp $";
  22. char *maildir_getlink(const char *filename)
  23. {
  24. #if     HAVE_READLINK
  25. size_t bufsiz;
  26. char *buf;
  27. bufsiz=0;
  28. buf=0;
  29. for (;;)
  30. {
  31. int n;
  32. if (buf) free(buf);
  33. bufsiz += 256;
  34. if ((buf=malloc(bufsiz)) == 0)
  35. {
  36. perror("malloc");
  37. return (0);
  38. }
  39. if ((n=readlink(filename, buf, bufsiz)) < 0)
  40. {
  41. free(buf);
  42. return (0);
  43. }
  44. if (n < bufsiz)
  45. {
  46. buf[n]=0;
  47. break;
  48. }
  49. }
  50. return (buf);
  51. #else
  52. return (0);
  53. #endif
  54. }
  55. int maildir_semisafeopen(const char *path, int mode, int perm)
  56. {
  57. #if HAVE_READLINK
  58. char *l=maildir_getlink(path);
  59. if (l)
  60. {
  61. int f;
  62. if (*l != '/')
  63. {
  64. char *q=malloc(strlen(path)+strlen(l)+2);
  65. char *s;
  66. if (!q)
  67. {
  68. free(l);
  69. return (-1);
  70. }
  71. strcpy(q, path);
  72. if ((s=strchr(q, '/')) != 0)
  73. s[1]=0;
  74. else *q=0;
  75. strcat(q, l);
  76. free(l);
  77. l=q;
  78. }
  79. f=maildir_safeopen(l, mode, perm);
  80. free(l);
  81. return (f);
  82. }
  83. #endif
  84. return (maildir_safeopen(path, mode, perm));
  85. }
  86. int maildir_safeopen(const char *path, int mode, int perm)
  87. {
  88. struct stat stat1, stat2;
  89. int fd=open(path, mode
  90. #ifdef O_NONBLOCK
  91. | O_NONBLOCK
  92. #else
  93. | O_NDELAY
  94. #endif
  95. , perm);
  96. if (fd < 0) return (fd);
  97. if (fcntl(fd, F_SETFL, 0) || fstat(fd, &stat1) || lstat(path, &stat2))
  98. {
  99. close(fd);
  100. return (-1);
  101. }
  102. if (stat1.st_dev != stat2.st_dev || stat1.st_ino != stat2.st_ino)
  103. {
  104. close(fd);
  105. errno=ENOENT;
  106. return (-1);
  107. }
  108. return (fd);
  109. }