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"
39 FILE *maildir_tmpcreate_fp(struct maildir_tmpcreate_info *info)
41 int fd=maildir_tmpcreate_fd(info);
58 static int maildir_tmpcreate_fd_do(struct maildir_tmpcreate_info *info);
60 #define KEEPTRYING (60 * 60)
63 int maildir_tmpcreate_fd(struct maildir_tmpcreate_info *info)
68 return (maildir_tmpcreate_fd_do(info));
70 for (i=0; i<KEEPTRYING / SLEEPFOR; i++)
72 int fd=maildir_tmpcreate_fd_do(info);
74 if (fd >= 0 || errno != EAGAIN)
83 static int maildir_tmpcreate_fd_do(struct maildir_tmpcreate_info *info)
85 const char *maildir=info->maildir;
86 const char *uniq=info->uniq;
87 const char *hostname=info->hostname;
89 char hostname_buf[256];
90 char time_buf[NUMBUFSIZE];
91 char usec_buf[NUMBUFSIZE];
92 char pid_buf[NUMBUFSIZE];
93 char len_buf[NUMBUFSIZE+3];
94 char dev_buf[NUMBUFSIZE];
95 char ino_buf[NUMBUFSIZE];
106 if (!hostname || !*hostname)
108 hostname_buf[sizeof(hostname_buf)-1]=0;
109 if (gethostname(hostname_buf, sizeof(hostname_buf)-1) < 0)
110 strcpy(hostname_buf, "localhost");
111 hostname=hostname_buf;
114 gettimeofday(&tv, NULL);
116 libmail_str_time_t(tv.tv_sec, time_buf);
117 libmail_str_time_t(tv.tv_usec, usec_buf);
118 libmail_str_pid_t(getpid(), pid_buf);
120 if (info->msgsize > 0)
122 strcpy(len_buf, ",S=");
123 libmail_str_size_t(info->msgsize, len_buf+3);
129 info->tmpname=malloc(strlen(maildir)+strlen(uniq)+
130 strlen(hostname)+strlen(time_buf)+
132 strlen(pid_buf)+strlen(len_buf)+100);
136 maildir_tmpcreate_free(info);
140 strcpy(info->tmpname, maildir);
141 strcat(info->tmpname, "/tmp/");
142 strcat(info->tmpname, time_buf);
143 strcat(info->tmpname, ".M");
144 strcat(info->tmpname, usec_buf);
145 strcat(info->tmpname, "P");
146 strcat(info->tmpname, pid_buf);
149 strcat(strcat(info->tmpname, "_"), uniq);
150 strcat(info->tmpname, ".");
151 strcat(info->tmpname, hostname);
152 strcat(info->tmpname, len_buf);
154 if (stat( info->tmpname, &stat_buf) == 0)
156 maildir_tmpcreate_free(info);
163 maildir_tmpcreate_free(info);
169 if ((fd=maildir_safeopen_stat(info->tmpname, O_CREAT|O_RDWR|O_TRUNC,
170 info->openmode, &stat_buf)) < 0)
172 maildir_tmpcreate_free(info);
176 libmail_strh_dev_t(stat_buf.st_dev, dev_buf);
177 libmail_strh_ino_t(stat_buf.st_ino, ino_buf);
182 info->newname=malloc(strlen(info->tmpname)+strlen(ino_buf)+
187 maildir_tmpcreate_free(info);
188 unlink(info->tmpname);
195 strcpy(info->newname, maildir);
196 strcat(info->newname, "/new/");
197 strcat(info->newname, time_buf);
198 strcat(info->newname, ".M");
199 strcat(info->newname, usec_buf);
200 strcat(info->newname, "P");
201 strcat(info->newname, pid_buf);
202 strcat(info->newname, "V");
203 strcat(info->newname, dev_buf);
204 strcat(info->newname, "I");
205 strcat(info->newname, ino_buf);
207 strcat(strcat(info->newname, "_"), uniq);
208 strcat(info->newname, ".");
209 strcat(info->newname, hostname);
210 strcat(info->newname, len_buf);
215 void maildir_tmpcreate_free(struct maildir_tmpcreate_info *info)
226 int maildir_movetmpnew(const char *tmpname, const char *newname)
228 if (link(tmpname, newname) == 0)
239 return rename(tmpname, newname);