2 ** Copyright 1998 - 2003 Double Precision, Inc.
3 ** See COPYING for distribution information.
6 #include "maildircreate.h"
7 #include "maildirmisc.h"
13 #if TIME_WITH_SYS_TIME
35 #include "numlib/numlib.h"
38 static const char rcsid[]="$Id: maildircreate.c,v 1.6 2003/01/26 04:07:03 mrsam Exp $";
40 FILE *maildir_tmpcreate_fp(struct maildir_tmpcreate_info *info)
42 int fd=maildir_tmpcreate_fd(info);
59 static int maildir_tmpcreate_fd_do(struct maildir_tmpcreate_info *info);
61 #define KEEPTRYING (60 * 60)
64 int maildir_tmpcreate_fd(struct maildir_tmpcreate_info *info)
69 return (maildir_tmpcreate_fd_do(info));
71 for (i=0; i<KEEPTRYING / SLEEPFOR; i++)
73 int fd=maildir_tmpcreate_fd_do(info);
75 if (fd >= 0 || errno != EAGAIN)
84 static int maildir_tmpcreate_fd_do(struct maildir_tmpcreate_info *info)
86 const char *maildir=info->maildir;
87 const char *uniq=info->uniq;
88 const char *hostname=info->hostname;
90 char hostname_buf[256];
91 char time_buf[NUMBUFSIZE];
92 char usec_buf[NUMBUFSIZE];
93 char pid_buf[NUMBUFSIZE];
94 char len_buf[NUMBUFSIZE+3];
95 char dev_buf[NUMBUFSIZE];
96 char ino_buf[NUMBUFSIZE];
107 if (!hostname || !*hostname)
109 hostname_buf[sizeof(hostname_buf)-1]=0;
110 if (gethostname(hostname_buf, sizeof(hostname_buf)-1) < 0)
111 strcpy(hostname_buf, "localhost");
112 hostname=hostname_buf;
115 gettimeofday(&tv, NULL);
117 libmail_str_time_t(tv.tv_sec, time_buf);
118 libmail_str_time_t(tv.tv_usec, usec_buf);
119 libmail_str_pid_t(getpid(), pid_buf);
121 if (info->msgsize > 0)
123 strcpy(len_buf, ",S=");
124 libmail_str_size_t(info->msgsize, len_buf+3);
130 info->tmpname=malloc(strlen(maildir)+strlen(uniq)+
131 strlen(hostname)+strlen(time_buf)+
133 strlen(pid_buf)+strlen(len_buf)+100);
137 maildir_tmpcreate_free(info);
141 strcpy(info->tmpname, maildir);
142 strcat(info->tmpname, "/tmp/");
143 strcat(info->tmpname, time_buf);
144 strcat(info->tmpname, ".M");
145 strcat(info->tmpname, usec_buf);
146 strcat(info->tmpname, "P");
147 strcat(info->tmpname, pid_buf);
150 strcat(strcat(info->tmpname, "_"), uniq);
151 strcat(info->tmpname, ".");
152 strcat(info->tmpname, hostname);
153 strcat(info->tmpname, len_buf);
155 if (stat( info->tmpname, &stat_buf) == 0)
157 maildir_tmpcreate_free(info);
164 maildir_tmpcreate_free(info);
170 if ((fd=maildir_safeopen_stat(info->tmpname, O_CREAT|O_RDWR|O_TRUNC,
171 info->openmode, &stat_buf)) < 0)
173 maildir_tmpcreate_free(info);
177 libmail_strh_dev_t(stat_buf.st_dev, dev_buf);
178 libmail_strh_ino_t(stat_buf.st_ino, ino_buf);
183 info->newname=malloc(strlen(info->tmpname)+strlen(ino_buf)+
188 maildir_tmpcreate_free(info);
189 unlink(info->tmpname);
196 strcpy(info->newname, maildir);
197 strcat(info->newname, "/new/");
198 strcat(info->newname, time_buf);
199 strcat(info->newname, ".M");
200 strcat(info->newname, usec_buf);
201 strcat(info->newname, "P");
202 strcat(info->newname, pid_buf);
203 strcat(info->newname, "V");
204 strcat(info->newname, dev_buf);
205 strcat(info->newname, "I");
206 strcat(info->newname, ino_buf);
208 strcat(strcat(info->newname, "_"), uniq);
209 strcat(info->newname, ".");
210 strcat(info->newname, hostname);
211 strcat(info->newname, len_buf);
216 void maildir_tmpcreate_free(struct maildir_tmpcreate_info *info)
227 int maildir_movetmpnew(const char *tmpname, const char *newname)
229 if (link(tmpname, newname) == 0)
240 return rename(tmpname, newname);