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

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. #if HAVE_DIRENT_H
  10. #include <dirent.h>
  11. #define NAMLEN(dirent) strlen((dirent)->d_name)
  12. #else
  13. #define dirent direct
  14. #define NAMLEN(dirent) (dirent)->d_namlen
  15. #if HAVE_SYS_NDIR_H
  16. #include <sys/ndir.h>
  17. #endif
  18. #if HAVE_SYS_DIR_H
  19. #include <sys/dir.h>
  20. #endif
  21. #if HAVE_NDIR_H
  22. #include <ndir.h>
  23. #endif
  24. #endif
  25. #include <sys/types.h>
  26. #include <sys/stat.h>
  27. #include <string.h>
  28. #include <stdlib.h>
  29. #include <time.h>
  30. #if HAVE_UNISTD_H
  31. #include <unistd.h>
  32. #endif
  33. #include <stdio.h>
  34. #include <ctype.h>
  35. #include <errno.h>
  36. #include <fcntl.h>
  37. #include "maildirmisc.h"
  38. #include "maildircreate.h"
  39. #include "maildirsharedrc.h"
  40. static const char rcsid[]="$Id: maildirshared.c,v 1.12 2000/05/07 17:14:24 mrsam Exp $";
  41. /* Prerequisited for shared folder support */
  42. #if HAVE_READLINK
  43. #if HAVE_SYMLINK
  44. #if HAVE_DBOBJ
  45. #define YES_WE_CAN_DO_SHARED 1
  46. #endif
  47. #endif
  48. #endif
  49. #if YES_WE_CAN_DO_SHARED
  50. #include "dbobj.h"
  51. static void list_sharable(const char *, const char *,
  52. void (*)(const char *, void *),
  53. void *);
  54. extern FILE *maildir_shared_fopen(const char *, const char *);
  55. extern void maildir_shared_fparse(char *, char **, char **);
  56. void maildir_list_sharable(const char *maildir,
  57. void (*func)(const char *, void *),
  58. void *voidp)
  59. {
  60. char buf[BUFSIZ];
  61. FILE *fp;
  62. char *p;
  63. int pass;
  64. if (!maildir) maildir=".";
  65. for (pass=0; pass<2; pass++)
  66. {
  67. fp=pass ? maildir_shared_fopen(maildir, "r")
  68. : fopen (MAILDIRSHAREDRC, "r");
  69. if (!fp) continue;
  70. while ((p=fgets(buf, sizeof(buf), fp)) != 0)
  71. {
  72. char *name, *dir;
  73. maildir_shared_fparse(p, &name, &dir);
  74. if (name)
  75. list_sharable(name, dir, func, voidp);
  76. }
  77. fclose(fp);
  78. }
  79. }
  80. static void list_sharable(const char *pfix, const char *path,
  81. void (*func)(const char *, void *),
  82. void *voidp)
  83. {
  84. DIR *dirp;
  85. struct dirent *de;
  86. struct stat stat_buf;
  87. dirp=opendir(path);
  88. while (dirp && (de=readdir(dirp)) != 0)
  89. {
  90. char *z;
  91. if (de->d_name[0] != '.') continue;
  92. if (strcmp(de->d_name, ".") == 0 ||
  93. strcmp(de->d_name, "..") == 0) continue;
  94. z=malloc(strlen(path)+strlen(de->d_name)+12);
  95. if (!z) continue;
  96. strcat(strcat(strcat(strcpy(z, path),
  97. "/"), de->d_name), "/cur/.");
  98. if (stat(z, &stat_buf))
  99. {
  100. free(z);
  101. continue;
  102. }
  103. free(z);
  104. z=malloc(strlen(pfix)+strlen(de->d_name)+1);
  105. if (!z) continue;
  106. strcat(strcpy(z, pfix), de->d_name);
  107. (*func)(z, voidp);
  108. free(z);
  109. }
  110. if (dirp) closedir(dirp);
  111. }
  112. int maildir_shared_subscribe(const char *maildir, const char *folder)
  113. {
  114. char linebuf[BUFSIZ];
  115. FILE *fp;
  116. char *p;
  117. char *name=strchr(folder, '.');
  118. char *s, *n, *dir;
  119. char *buf, *link;
  120. unsigned l;
  121. int pass;
  122. if (!name)
  123. {
  124. errno=EINVAL;
  125. return (-1);
  126. }
  127. if (!maildir) maildir=".";
  128. p=maildir_shareddir(maildir, folder); /* valid folder name? */
  129. if (!p)
  130. {
  131. errno=EINVAL;
  132. return (-1);
  133. }
  134. free(p);
  135. p=0;
  136. for (pass=0; pass<2; pass++)
  137. {
  138. fp=pass ? maildir_shared_fopen(maildir, "r")
  139. : fopen (MAILDIRSHAREDRC, "r");
  140. if (!fp) continue;
  141. while ((p=fgets(linebuf, sizeof(linebuf), fp)) != 0)
  142. {
  143. maildir_shared_fparse(p, &n, &dir);
  144. if (!n) continue;
  145. if (strlen(n) == name - folder ||
  146. memcmp(n, folder, name-folder) == 0) break;
  147. }
  148. fclose(fp);
  149. if (p) break;
  150. }
  151. if (p)
  152. {
  153. /*
  154. ** We will create:
  155. **
  156. **  maildir/shared-folders/ (name-folder) /(name)
  157. **
  158. **  there we'll have subdirs cur/new/tmp  and shared link
  159. */
  160. l=sizeof("/" SHAREDSUBDIR "//shared") +
  161. strlen(maildir) + strlen(folder);
  162. buf=malloc(l);
  163. if (!buf) return (-1);
  164. strcat(strcpy(buf, maildir), "/" SHAREDSUBDIR);
  165. mkdir(buf, 0700);
  166. strcat(buf, "/");
  167. strncat(buf, folder, name-folder);
  168. mkdir(buf, 0700);
  169. strcat(buf, "/");
  170. strcat(buf, name+1);
  171. if ( mkdir(buf, 0700)) return (-1);
  172. s=buf+strlen(buf);
  173. *s++='/';
  174. strcpy(s, "tmp");
  175. if ( mkdir(buf, 0700))
  176. {
  177. s[-1]=0;
  178. rmdir(buf);
  179. free(buf);
  180. return (-1);
  181. }
  182. strcpy(s, "cur");
  183. if ( mkdir(buf, 0700))
  184. {
  185. strcpy(s, "tmp");
  186. rmdir(buf);
  187. s[-1]=0;
  188. rmdir(buf);
  189. free(buf);
  190. return (-1);
  191. }
  192. strcpy(s, "new");
  193. if ( mkdir(buf, 0700))
  194. {
  195. strcpy(s, "cur");
  196. rmdir(buf);
  197. strcpy(s, "tmp");
  198. rmdir(buf);
  199. s[-1]=0;
  200. rmdir(buf);
  201. free(buf);
  202. return (-1);
  203. }
  204. strcpy(s, "shared");
  205. if ((link=malloc(strlen(dir)+strlen(name)+2)) == 0 ||
  206. symlink( strcat(strcat(strcpy(link, dir), "/"), name),
  207. buf))
  208. {
  209. if (link) free(link);
  210. strcpy(s, "new");
  211. rmdir(buf);
  212. strcpy(s, "cur");
  213. rmdir(buf);
  214. strcpy(s, "tmp");
  215. rmdir(buf);
  216. s[-1]=0;
  217. rmdir(buf);
  218. free(buf);
  219. return (-1);
  220. }
  221. free(link);
  222. free(buf);
  223. return (0);
  224. }
  225. errno=ENOENT;
  226. return (-1);
  227. }
  228. void maildir_list_shared(const char *maildir,
  229. void (*func)(const char *, void *),
  230. void *voidp)
  231. {
  232. char *sh;
  233. DIR *dirp;
  234. struct dirent *de;
  235. if (!maildir) maildir=".";
  236. sh=malloc(strlen(maildir)+sizeof("/" SHAREDSUBDIR));
  237. if (!sh) return;
  238. strcat(strcpy(sh, maildir), "/" SHAREDSUBDIR);
  239. dirp=opendir(sh);
  240. while (dirp && (de=readdir(dirp)) != 0)
  241. {
  242. DIR *dirp2;
  243. struct dirent *de2;
  244. char *z;
  245. if (de->d_name[0] == '.') continue;
  246. z=malloc(strlen(sh)+strlen(de->d_name)+2);
  247. if (!z) continue;
  248. strcat(strcat(strcpy(z, sh), "/"), de->d_name);
  249. dirp2=opendir(z);
  250. free(z);
  251. while (dirp2 && (de2=readdir(dirp2)) != 0)
  252. {
  253. char *s;
  254. if (de2->d_name[0] == '.') continue;
  255. s=malloc(strlen(de->d_name)+strlen(de2->d_name)+2);
  256. if (!s) continue;
  257. strcat(strcat(strcpy(s, de->d_name), "."), de2->d_name);
  258. (*func)(s, voidp);
  259. free(s);
  260. }
  261. if (dirp2) closedir(dirp2);
  262. }
  263. free(sh);
  264. if (dirp) closedir(dirp);
  265. }
  266. int maildir_shared_unsubscribe(const char *maildir, const char *folder)
  267. {
  268. char *s;
  269. s=maildir_shareddir(maildir, folder);
  270. if (!s) return (-1);
  271. if (maildir_mddelete(s))
  272. {
  273. free(s);
  274. return (-1);
  275. }
  276. *strrchr(s, '/')=0; /* Try to remove the whole folder dir */
  277. rmdir(s);
  278. free(s);
  279. return (0);
  280. }
  281. char *maildir_shareddir(const char *maildir, const char *sharedname)
  282. {
  283. char    *p, *q;
  284. const char *r;
  285. size_t  l;
  286. if (!maildir)   maildir=".";
  287.         l=strlen(maildir);
  288. if (strchr(sharedname, '.') == 0 || *sharedname == '.' ||
  289. strchr(sharedname, '/'))
  290. {
  291. errno=EINVAL;
  292. return (0);
  293. }
  294. for (r=sharedname; *r; r++)
  295. {
  296. if (*r == '.' && (r[1] == '.' || r[1] == ''))
  297. {
  298. errno=EINVAL;
  299. return (0);
  300. }
  301. }
  302. p=malloc(strlen(maildir)+sizeof("/" SHAREDSUBDIR "/")+strlen(sharedname));
  303. if (!p) return (0);
  304.         *p=0;
  305.         if (strcmp(maildir, "."))
  306. strcat(strcpy(p, maildir), "/");
  307. strcat(p, SHAREDSUBDIR "/");
  308. q=p+strlen(p);
  309. strcpy(q, sharedname);
  310. *strchr(q, '.')='/';
  311. return (p);
  312. }
  313. /*                    LET'S SYNC IT                  */
  314. static void do_maildir_shared_sync(const char *, const char *);
  315. void maildir_shared_sync(const char *dir)
  316. {
  317. char *shareddir;
  318. char *buf;
  319. shareddir=malloc(strlen(dir)+sizeof("/shared"));
  320. if (!shareddir)
  321. {
  322. perror("malloc");
  323. return;
  324. }
  325. strcat(strcpy(shareddir, dir),"/shared");
  326. buf=maildir_getlink(shareddir);
  327. free(shareddir);
  328. if (buf)
  329. {
  330. do_maildir_shared_sync(dir, buf);
  331. free(buf);
  332. }
  333. }
  334. /* Step 1 - safely create a temporary database */
  335. static int create_db(struct dbobj *obj,
  336. const char *dir,
  337. char **dbname)
  338. {
  339. int rc;
  340. char *tmpname, *dummy;
  341. for (;;)
  342. {
  343. int fd;
  344. rc=maildir_try_create(dir, "sync", 0, &tmpname, &dummy);
  345. if (rc < 0)
  346. {
  347. perror(dir);
  348. return (-1);
  349. }
  350. if (rc == 0)
  351. {
  352. fd=maildir_safeopen(tmpname, O_RDWR|O_CREAT|O_EXCL,
  353. 0600);
  354. if (fd >= 0)
  355. {
  356. dbobj_init(obj);
  357. if (dbobj_open(obj, tmpname, "N") < 0)
  358. {
  359. perror(tmpname);
  360. close(fd);
  361. unlink(tmpname);
  362. free(tmpname);
  363. free(dummy);
  364. return (-1);
  365. }
  366. close(fd);
  367. free(dummy);
  368. break;
  369. }
  370. perror(tmpname);
  371. free(tmpname);
  372. free(dummy);
  373. }
  374. sleep(3);
  375. }
  376. *dbname=tmpname;
  377. return (0);
  378. }
  379. /*
  380. ** Populate the DB by building the db with the messages in the sharable
  381. ** folder's cur.  The key is the stripped message filename, the value is
  382. ** the complete message filename.
  383. */
  384. static int build_db(const char *shared, struct dbobj *obj)
  385. {
  386. char *dummy=malloc(strlen(shared)+sizeof("/cur"));
  387. DIR *dirp;
  388. struct dirent *de;
  389. if (!dummy)
  390. {
  391. perror("malloc");
  392. return (-1);
  393. }
  394. strcat(strcpy(dummy, shared), "/cur");
  395. dirp=opendir(dummy);
  396. while (dirp && (de=readdir(dirp)) != 0)
  397. {
  398. char *a, *b;
  399. char *c;
  400. if (de->d_name[0] == '.')
  401. continue;
  402. if ((a=malloc(strlen(de->d_name)+1)) == 0)
  403. {
  404. perror("malloc");
  405. closedir(dirp);
  406. free(dummy);
  407. return (-1);
  408. }
  409. if ((b=malloc(strlen(de->d_name)+1)) == 0)
  410. {
  411. perror("malloc");
  412. closedir(dirp);
  413. free(dummy);
  414. free(a);
  415. return (-1);
  416. }
  417. strcpy(a, de->d_name);
  418. strcpy(b, de->d_name);
  419. c=strrchr(a, ':');
  420. if (c) *c=0;
  421. if (dbobj_store(obj, a, strlen(a), b, strlen(b), "R"))
  422. {
  423. perror("dbobj_store");
  424. free(a);
  425. free(b);
  426. closedir(dirp);
  427. free(dummy);
  428. return (-1);
  429. }
  430. free(a);
  431. free(b);
  432. }
  433. if (dirp) closedir(dirp);
  434. free(dummy);
  435. return (0);
  436. }
  437. static int update_link(const char *,
  438. const char *, const char *,
  439. const char *,
  440. const char *,
  441. size_t);
  442. /*
  443. ** Now, read our synced cur directory, and make sure that the soft
  444. ** links are up to date.  Remove messages that have been deleted from
  445. ** the sharable maildir, and make sure that the remaining links are
  446. ** valid.
  447. */
  448. static int update_cur(const char *cur, const char *shared, struct dbobj *obj)
  449. {
  450. DIR *dirp;
  451. struct dirent *de;
  452. char *p;
  453. dirp=opendir(cur);
  454. while (dirp && (de=readdir(dirp)) != 0)
  455. {
  456. char *cur_base;
  457. char *cur_name_ptr;
  458. size_t cur_name_len;
  459. char *linked_name_buf;
  460. size_t linked_name_len;
  461. int n;
  462. if (de->d_name[0] == '.') continue;
  463. /*
  464. ** Strip the maildir flags, and look up the message in the
  465. ** db.
  466. */
  467. cur_base=malloc(strlen(de->d_name)+1);
  468. if (!cur_base)
  469. {
  470. perror("malloc");
  471. closedir(dirp);
  472. return (-1);
  473. }
  474. strcpy(cur_base, de->d_name);
  475. p=strrchr(cur_base, ':');
  476. if (p) *p=0;
  477. cur_name_ptr=dbobj_fetch(obj, cur_base, strlen(cur_base),
  478. &cur_name_len, "");
  479. /* If it's there, delete the db entry. */
  480. if (cur_name_ptr)
  481. dbobj_delete(obj, cur_base, strlen(cur_base));
  482. /*
  483. ** We'll either delete this soft link, or check its
  484. ** contents, so we better build its complete pathname in
  485. ** any case.
  486. */
  487. free(cur_base);
  488. cur_base=malloc(strlen(de->d_name)+strlen(cur)+2);
  489. if (!cur_base)
  490. {
  491. perror("malloc");
  492. if (cur_name_ptr) free(cur_name_ptr);
  493. closedir(dirp);
  494. return (-1);
  495. }
  496. strcat(strcat(strcpy(cur_base, cur), "/"), de->d_name);
  497. if (!cur_name_ptr) /* Removed from sharable dir */
  498. {
  499. unlink(cur_base);
  500. free(cur_base);
  501. continue;
  502. }
  503. linked_name_len=strlen(shared)+strlen(de->d_name)+100;
  504. /* should be enough */
  505. if ((linked_name_buf=malloc(linked_name_len)) == 0)
  506. {
  507. perror("malloc");
  508. free(cur_base);
  509. free(cur_name_ptr);
  510. closedir(dirp);
  511. return (-1);
  512. }
  513. if ((n=readlink(cur_base, linked_name_buf, linked_name_len))< 0)
  514. {
  515. /* This is stupid, let's just unlink this nonsense */
  516. n=0;
  517. }
  518. if (n == 0 || n >= linked_name_len ||
  519. (linked_name_buf[n]=0,
  520. update_link(cur,
  521. cur_base, linked_name_buf, shared, cur_name_ptr,
  522. cur_name_len)))
  523. {
  524. unlink(cur_base);
  525. free(linked_name_buf);
  526. free(cur_base);
  527. free(cur_name_ptr);
  528. closedir(dirp);
  529. return (-1);
  530. }
  531. free(cur_base);
  532. free(linked_name_buf);
  533. free(cur_name_ptr);
  534. }
  535. if (dirp) closedir(dirp);
  536. return (0);
  537. }
  538. /* Update the link pointer */
  539. static int update_link(const char *curdir,
  540. const char *linkname, const char *linkvalue,
  541. const char *shareddir,
  542. const char *msgfilename,
  543. size_t msgfilenamelen)
  544. {
  545. char *p=malloc(strlen(shareddir)+sizeof("/cur/")+msgfilenamelen);
  546. char *q;
  547. int rc;
  548. char *tmpname, *dummy;
  549. if (!p)
  550. {
  551. perror("malloc");
  552. return (-1);
  553. }
  554. strcat(strcpy(p, shareddir), "/cur/");
  555. q=p+strlen(p);
  556. memcpy(q, msgfilename, msgfilenamelen);
  557. q[msgfilenamelen]=0;
  558. if (linkvalue && strcmp(p, linkvalue) == 0)
  559. {
  560. /* the link is good */
  561. free(p);
  562. return (0);
  563. }
  564. /* Ok, we want this to be an atomic operation. */
  565. for (;;)
  566. {
  567. rc=maildir_try_create(curdir, "relink", 0, &tmpname, &dummy);
  568. if (rc < 0)
  569. {
  570. perror(curdir);
  571. return (-1);
  572. }
  573. if (rc == 0)
  574. {
  575. free(dummy);
  576. if (symlink(p, tmpname))
  577. {
  578. perror(tmpname);
  579. free(tmpname);
  580. free(p);
  581. return (-1);
  582. }
  583. break;
  584. }
  585. sleep(3);
  586. }
  587. free(p);
  588. if (rename(tmpname, linkname))
  589. {
  590. perror(linkname);
  591. unlink(tmpname);
  592. free(tmpname);
  593. return (-1);
  594. }
  595. free(tmpname);
  596. return (0);
  597. }
  598. /* and now, anything that's left in the temporary db must be new messages */
  599. static int newmsgs(const char *cur, const char *shared, struct dbobj *obj)
  600. {
  601. char *key, *val;
  602. size_t keylen, vallen;
  603. int rc;
  604. char *tmpname, *dummy;
  605. for (key=dbobj_firstkey(obj, &keylen, &val, &vallen); key;
  606. key=dbobj_nextkey(obj, &keylen, &val, &vallen))
  607. {
  608. char *slink=malloc(strlen(shared)+sizeof("/cur/")+vallen);
  609. char *q;
  610. if (!slink)
  611. {
  612. free(val);
  613. return (-1);
  614. }
  615. strcat(strcpy(slink, shared), "/cur/");
  616. q=slink+strlen(slink);
  617. memcpy(q, val, vallen);
  618. q[vallen]=0;
  619. free(val);
  620. for (;;)
  621. {
  622. rc=maildir_try_create(cur, "newlink",
  623. 0, &tmpname, &dummy);
  624. if (rc < 0)
  625. {
  626. perror(cur);
  627. free(slink);
  628. return (-1);
  629. }
  630. if (rc == 0)
  631. {
  632. free(dummy);
  633. if (symlink(slink, tmpname))
  634. {
  635. perror(tmpname);
  636. free(tmpname);
  637. free(slink);
  638. return (-1);
  639. }
  640. break;
  641. }
  642. sleep(3);
  643. }
  644. free(slink);
  645. slink=malloc(strlen(cur)+sizeof("/new/:2,")+keylen);
  646. if (!slink)
  647. {
  648. perror("malloc");
  649. unlink(tmpname);
  650. free(tmpname);
  651. }
  652. strcat(strcpy(slink, cur), "/new/");
  653. q=slink+strlen(slink);
  654. memcpy(q, key, keylen);
  655. strcpy(q+keylen, ":2,");
  656. if (rename(tmpname, slink))
  657. {
  658. perror(slink);
  659. unlink(tmpname);
  660. free(tmpname);
  661. }
  662. }
  663. return (0);
  664. }
  665. static void do_maildir_shared_sync(const char *dir, const char *shared)
  666. {
  667. struct dbobj obj;
  668. char *dbname;
  669. char *cur;
  670. char *shared_update_name;
  671. struct stat stat1, stat2;
  672. int fd;
  673. maildir_purgetmp(dir); /* clean up after myself */
  674. maildir_getnew(dir, 0);
  675. maildir_purgetmp(shared);
  676. maildir_getnew(shared, 0);
  677. /* Figure out if we REALLY need to sync something */
  678. shared_update_name=malloc(strlen(dir)+sizeof("/shared-timestamp"));
  679. if (!shared_update_name) return;
  680. strcat(strcpy(shared_update_name, dir), "/shared-timestamp");
  681. cur=malloc(strlen(shared)+sizeof("/new"));
  682. if (!cur)
  683. {
  684. free(shared_update_name);
  685. return;
  686. }
  687. if (stat(shared_update_name, &stat1) == 0)
  688. {
  689. if ( stat( strcat(strcpy(cur, shared), "/new"), &stat2) == 0 &&
  690. stat2.st_mtime < stat1.st_mtime &&
  691. stat( strcat(strcpy(cur, shared), "/cur"), &stat2)
  692. == 0 && stat2.st_mtime < stat1.st_mtime)
  693. {
  694. free(shared_update_name);
  695. free(cur);
  696. return;
  697. }
  698. }
  699. if ((fd=maildir_safeopen(shared_update_name, O_RDWR|O_CREAT, 0600))>= 0)
  700. {
  701. write(fd, "", 1);
  702. close(fd);
  703. }
  704. if (create_db(&obj, dir, &dbname)) return;
  705. if (build_db(shared, &obj))
  706. {
  707. dbobj_close(&obj);
  708. unlink(dbname);
  709. free(dbname);
  710. return;
  711. }
  712. if ((cur=malloc(strlen(dir)+sizeof("/cur"))) == 0)
  713. {
  714. perror("malloc");
  715. dbobj_close(&obj);
  716. unlink(dbname);
  717. free(dbname);
  718. return;
  719. }
  720. strcat(strcpy(cur, dir), "/cur");
  721. if (update_cur(cur, shared, &obj) == 0)
  722. {
  723. strcat(strcpy(cur, dir), "/new");
  724. if (update_cur(cur, shared, &obj) == 0)
  725. {
  726. *strrchr(cur, '/')=0; /* Chop off the /new */
  727. newmsgs(cur, shared, &obj);
  728. }
  729. }
  730. free(cur);
  731. dbobj_close(&obj);
  732. unlink(dbname);
  733. free(dbname);
  734. }
  735. int maildir_sharedisro(const char *maildir)
  736. {
  737. char *p=malloc(strlen(maildir)+sizeof("/shared/cur"));
  738. if (!p)
  739. {
  740. perror("malloc");
  741. return (-1);
  742. }
  743. strcat(strcpy(p, maildir), "/shared/cur");
  744. if (access(p, W_OK) == 0)
  745. {
  746. free(p);
  747. return (0);
  748. }
  749. free(p);
  750. return (1);
  751. }
  752. int maildir_unlinksharedmsg(const char *filename)
  753. {
  754. char *buf=maildir_getlink(filename);
  755. if (buf)
  756. {
  757. if (access(buf, 0) == 0)
  758. {
  759. if (unlink(buf))
  760. {
  761. free(buf);
  762. return (-1);
  763. }
  764. }
  765. free(buf);
  766. }
  767. unlink(filename);
  768. return (0);
  769. }
  770. #else
  771. /* We cannot implement sharing */
  772. void maildir_list_sharable(const char *maildir,
  773. void (*func)(const char *, void *),
  774. void *voidp)
  775. {
  776. }
  777. int maildir_shared_subscribe(const char *maildir, const char *folder)
  778. {
  779. errno=EINVAL;
  780. return (-1);
  781. }
  782. void maildir_list_shared(const char *maildir,
  783. void (*func)(const char *, void *),
  784. void *voidp)
  785. {
  786. }
  787. int maildir_shared_unsubscribe(const char *maildir, const char *folder)
  788. {
  789. errno=EINVAL;
  790. return (-1);
  791. }
  792. char *maildir_shareddir(const char *maildir, const char *sharedname)
  793. {
  794. errno=EINVAL;
  795. return (0);
  796. }
  797. void maildir_shared_sync(const char *maildir)
  798. {
  799. }
  800. int maildir_sharedisro(const char *maildir)
  801. {
  802. return (-1);
  803. }
  804. int maildir_unlinksharedmsg(const char *filename)
  805. {
  806. return (-1);
  807. }
  808. #endif