Commit c2b48051 c2b4805128f2619235396726a116331606729e62 by Sergey Poznyakoff

file_stream: Bugfixes

* libmailutils/stream/file_stream.c (fd_open): Remove file state
checks: it is the responsibility of the caller.
Set autoclose on the *stream* flags (bugfix, previously the underlying
fd was never closed).
Clear MU_STREAM_SEEK flag if seek fails.
(_mu_file_stream_create): Remove assignment to stream.error_string
* include/mailutils/stream.h (MU_STREAM_ALLOW_LINKS): Remove flag.
* libmailutils/base/amd.c (amd_message_stream_open): Initialize flags
to 0.
1 parent da9c204e
...@@ -46,7 +46,7 @@ enum mu_buffer_type ...@@ -46,7 +46,7 @@ enum mu_buffer_type
46 #define MU_STREAM_AUTOCLOSE 0x00000040 46 #define MU_STREAM_AUTOCLOSE 0x00000040
47 /* Not used. Intended for mailboxes only. */ 47 /* Not used. Intended for mailboxes only. */
48 #define MU_STREAM_NONLOCK 0x00000080 48 #define MU_STREAM_NONLOCK 0x00000080
49 #define MU_STREAM_ALLOW_LINKS 0x00000100 49 /* Not used as well 0x00000100 */
50 /* FIXME: This one affects only mailboxes */ 50 /* FIXME: This one affects only mailboxes */
51 #define MU_STREAM_QACCESS 0x00000200 51 #define MU_STREAM_QACCESS 0x00000200
52 52
......
...@@ -1589,7 +1589,7 @@ amd_message_stream_open (struct _amd_message *mhm) ...@@ -1589,7 +1589,7 @@ amd_message_stream_open (struct _amd_message *mhm)
1589 struct _amd_data *amd = mhm->amd; 1589 struct _amd_data *amd = mhm->amd;
1590 char *filename; 1590 char *filename;
1591 int status; 1591 int status;
1592 int flags = MU_STREAM_ALLOW_LINKS; 1592 int flags = 0;
1593 1593
1594 status = amd->cur_msg_file_name (mhm, &filename); 1594 status = amd->cur_msg_file_name (mhm, &filename);
1595 if (status) 1595 if (status)
......
...@@ -37,8 +37,6 @@ ...@@ -37,8 +37,6 @@
37 #include <mailutils/sys/file_stream.h> 37 #include <mailutils/sys/file_stream.h>
38 #include <mailutils/util.h> 38 #include <mailutils/util.h>
39 39
40 #define MU_FSTR_ERROR_NOREG (MU_ERR_LAST+1)
41
42 static int 40 static int
43 fd_read (struct _mu_stream *str, char *buf, size_t size, size_t *pret) 41 fd_read (struct _mu_stream *str, char *buf, size_t size, size_t *pret)
44 { 42 {
...@@ -107,7 +105,6 @@ fd_open (struct _mu_stream *str) ...@@ -107,7 +105,6 @@ fd_open (struct _mu_stream *str)
107 /* Oops bail out. */ 105 /* Oops bail out. */
108 if (errno != ENOENT) 106 if (errno != ENOENT)
109 return errno; 107 return errno;
110 /* Race condition here when creating the file ??. */
111 fd = open (fstr->filename, oflg|O_CREAT|O_EXCL, 108 fd = open (fstr->filename, oflg|O_CREAT|O_EXCL,
112 0600 | mu_stream_flags_to_mode (fstr->stream.flags, 0)); 109 0600 | mu_stream_flags_to_mode (fstr->stream.flags, 0));
113 } 110 }
...@@ -117,41 +114,13 @@ fd_open (struct _mu_stream *str) ...@@ -117,41 +114,13 @@ fd_open (struct _mu_stream *str)
117 114
118 if (fd == -1) 115 if (fd == -1)
119 return errno; 116 return errno;
120
121 if (!(fstr->stream.flags & MU_STREAM_ALLOW_LINKS)
122 && (fstr->stream.flags & (MU_STREAM_CREAT | MU_STREAM_RDWR |
123 MU_STREAM_APPEND)))
124 {
125 struct stat fdbuf, filebuf;
126 117
127 /* The following two stats should never fail. */ 118 if (lseek (fd, 0, SEEK_SET) == -1)
128 if (fstat (fd, &fdbuf) == -1 119 str->flags &= ~MU_STREAM_SEEK;
129 || lstat (fstr->filename, &filebuf) == -1)
130 {
131 close (fd);
132 return errno;
133 }
134
135 /* Now check that: file and fd reference the same file,
136 file only has one link, file is plain file. */
137 if ((fdbuf.st_dev != filebuf.st_dev
138 || fdbuf.st_ino != filebuf.st_ino
139 || fdbuf.st_nlink != 1
140 || filebuf.st_nlink != 1
141 || (fdbuf.st_mode & S_IFMT) != S_IFREG))
142 {
143 /* FIXME: Be silent */
144 close (fd);
145 return MU_FSTR_ERROR_NOREG;
146 }
147 }
148 120
149 if (fd < 0)
150 return errno;
151
152 /* Make sure it will be closed */ 121 /* Make sure it will be closed */
153 fstr->flags |= MU_STREAM_AUTOCLOSE; 122 str->flags |= MU_STREAM_AUTOCLOSE;
154 123
155 fstr->fd = fd; 124 fstr->fd = fd;
156 return 0; 125 return 0;
157 } 126 }
...@@ -190,15 +159,6 @@ fd_done (struct _mu_stream *str) ...@@ -190,15 +159,6 @@ fd_done (struct _mu_stream *str)
190 free (fstr->echo_state); 159 free (fstr->echo_state);
191 } 160 }
192 161
193 const char *
194 fd_error_string (struct _mu_stream *str, int rc)
195 {
196 if (rc == MU_FSTR_ERROR_NOREG)
197 return _("must be a plain file with one link");
198 else
199 return mu_strerror (rc);
200 }
201
202 #ifndef TCSASOFT 162 #ifndef TCSASOFT
203 # define TCSASOFT 0 163 # define TCSASOFT 0
204 #endif 164 #endif
...@@ -353,7 +313,6 @@ _mu_file_stream_create (struct _mu_file_stream **pstream, size_t size, ...@@ -353,7 +313,6 @@ _mu_file_stream_create (struct _mu_file_stream **pstream, size_t size,
353 str->stream.ctl = fd_ioctl; 313 str->stream.ctl = fd_ioctl;
354 str->stream.wait = fd_wait; 314 str->stream.wait = fd_wait;
355 str->stream.truncate = fd_truncate; 315 str->stream.truncate = fd_truncate;
356 str->stream.error_string = fd_error_string;
357 316
358 if (filename) 317 if (filename)
359 str->filename = mu_strdup (filename); 318 str->filename = mu_strdup (filename);
......