Rewritten
Showing
1 changed file
with
76 additions
and
47 deletions
... | @@ -17,9 +17,58 @@ | ... | @@ -17,9 +17,58 @@ |
17 | 17 | ||
18 | #include "imap4d.h" | 18 | #include "imap4d.h" |
19 | 19 | ||
20 | /* | 20 | struct scan_data |
21 | * | 21 | { |
22 | */ | 22 | int result; |
23 | char *name; | ||
24 | FILE *tmp; | ||
25 | }; | ||
26 | |||
27 | static int | ||
28 | scan_mailbox_list (char *filename, | ||
29 | int (*handler) (struct scan_data *data, char *name), | ||
30 | struct scan_data *data) | ||
31 | { | ||
32 | FILE *fp; | ||
33 | char buffer[124]; | ||
34 | |||
35 | fp = fopen (filename, "r"); | ||
36 | if (!fp) | ||
37 | return -1; | ||
38 | |||
39 | while (fgets (buffer, sizeof (buffer), fp)) | ||
40 | { | ||
41 | size_t n = strlen (buffer); | ||
42 | if (n && buffer[n - 1] == '\n') | ||
43 | buffer[n - 1] = '\0'; | ||
44 | if (handler (data, buffer)) | ||
45 | break; | ||
46 | } | ||
47 | fclose (fp); | ||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | static int | ||
52 | scan_only (struct scan_data *data, char *name) | ||
53 | { | ||
54 | if (strcmp (data->name, name) == 0) | ||
55 | { | ||
56 | data->result = 1; | ||
57 | return 1; | ||
58 | } | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | static int | ||
63 | unsubscribe (struct scan_data *data, char *name) | ||
64 | { | ||
65 | if (strcmp (data->name, name)) | ||
66 | { | ||
67 | fputs (name, data->tmp); | ||
68 | fputs ("\n", data->tmp); | ||
69 | } | ||
70 | return 0; | ||
71 | } | ||
23 | 72 | ||
24 | int | 73 | int |
25 | imap4d_unsubscribe (struct imap4d_command *command, char *arg) | 74 | imap4d_unsubscribe (struct imap4d_command *command, char *arg) |
... | @@ -27,62 +76,42 @@ imap4d_unsubscribe (struct imap4d_command *command, char *arg) | ... | @@ -27,62 +76,42 @@ imap4d_unsubscribe (struct imap4d_command *command, char *arg) |
27 | char *sp = NULL; | 76 | char *sp = NULL; |
28 | char *name; | 77 | char *name; |
29 | char *file; | 78 | char *file; |
30 | FILE *fp; | 79 | struct scan_data sd; |
31 | 80 | int rc; | |
81 | |||
32 | name = util_getword (arg, &sp); | 82 | name = util_getword (arg, &sp); |
33 | util_unquote (&name); | 83 | util_unquote (&name); |
34 | if (!name || *name == '\0') | 84 | if (!name || *name == '\0') |
35 | return util_finish (command, RESP_BAD, "Too few arguments"); | 85 | return util_finish (command, RESP_BAD, "Too few arguments"); |
36 | 86 | ||
37 | asprintf (&file, "%s/.mailboxlist", homedir); | 87 | asprintf (&file, "%s/.mailboxlist", homedir); |
38 | fp = fopen (file, "r"); | 88 | sd.result = 0; |
39 | free (file); | 89 | sd.name = name; |
40 | if (fp) | 90 | |
91 | rc = scan_mailbox_list (file, scan_only, &sd); | ||
92 | if (rc == 0) | ||
41 | { | 93 | { |
42 | char buffer[124]; | 94 | if (sd.result) |
43 | int found = 0; | ||
44 | while (fgets (buffer, sizeof (buffer), fp)) | ||
45 | { | ||
46 | size_t n = strlen (buffer); | ||
47 | if (n && buffer[n - 1] == '\n') | ||
48 | buffer[n - 1] = '\0'; | ||
49 | if (strcmp (buffer, name) == 0) | ||
50 | { | ||
51 | found = 1; | ||
52 | break; | ||
53 | } | ||
54 | } | ||
55 | if (found) | ||
56 | { | 95 | { |
57 | FILE *fp2; | 96 | char *tmpname = NULL; |
58 | asprintf (&file, "%s/.mailboxlist.%d", homedir, getpid ()); | 97 | asprintf (&tmpname, "%s.%d", file, getpid ()); |
59 | fp2 = fopen (file, "a"); | 98 | sd.tmp = fopen (tmpname, "a"); |
60 | if (fp2) | 99 | if (!sd.tmp) |
100 | rc = -1; | ||
101 | else | ||
61 | { | 102 | { |
62 | rewind (fp); | 103 | rc = scan_mailbox_list (file, unsubscribe, &sd); |
63 | while (fgets (buffer, sizeof (buffer), fp)) | 104 | fclose (sd.tmp); |
64 | { | 105 | if (rc == 0) |
65 | size_t n = strlen (buffer); | 106 | rename (tmpname, file); |
66 | if (n && buffer[n - 1] == '\n') | ||
67 | buffer[n - 1] = '\0'; | ||
68 | if (strcmp (buffer, name) == 0) | ||
69 | continue; | ||
70 | fputs (buffer, fp2); | ||
71 | fputs ("\n", fp2); | ||
72 | } | ||
73 | fclose (fp2); | ||
74 | remove (file); | ||
75 | } | 107 | } |
76 | free (file); | 108 | free (tmpname); |
77 | } | ||
78 | else | ||
79 | { | ||
80 | fclose (fp); | ||
81 | return util_finish (command, RESP_NO, "Can not unsubscribe"); | ||
82 | } | 109 | } |
83 | fclose (fp); | ||
84 | } | 110 | } |
85 | else | 111 | |
112 | free (file); | ||
113 | if (rc) | ||
86 | return util_finish (command, RESP_NO, "Can not unsubscribe"); | 114 | return util_finish (command, RESP_NO, "Can not unsubscribe"); |
115 | |||
87 | return util_finish (command, RESP_OK, "Completed"); | 116 | return util_finish (command, RESP_OK, "Completed"); |
88 | } | 117 | } | ... | ... |
-
Please register or sign in to post a comment