1: /* rmf.c - remove a folder */ 2: 3: #include "../h/mh.h" 4: #include <stdio.h> 5: #include <sys/types.h> 6: #ifndef BSD42 7: #ifndef SYS5 8: #include <ndir.h> 9: #else SYS5 10: #include <dir.h> 11: #endif SYS5 12: #else BSD42 13: #include <sys/dir.h> 14: #endif BSD42 15: 16: /* */ 17: 18: static struct swit switches[] = { 19: #define INTRSW 0 20: "interactive", 0, 21: #define NINTRSW 1 22: "nointerative", 0, 23: 24: #define HELPSW 2 25: "help", 4, 26: 27: NULL, NULL 28: }; 29: 30: /* */ 31: 32: /* ARGSUSED */ 33: 34: main (argc, argv) 35: int argc; 36: char *argv[]; 37: { 38: int defolder = 0, 39: interactive = -1; 40: char *cp, 41: *folder = NULL, 42: newfolder[BUFSIZ], 43: buf[100], 44: **ap, 45: **argp, 46: *arguments[MAXARGS]; 47: 48: invo_name = r1bindex (argv[0], '/'); 49: if ((cp = m_find (invo_name)) != NULL) { 50: ap = brkstring (cp = getcpy (cp), " ", "\n"); 51: ap = copyip (ap, arguments); 52: } 53: else 54: ap = arguments; 55: (void) copyip (argv + 1, ap); 56: argp = arguments; 57: 58: /* */ 59: 60: while (cp = *argp++) { 61: if (*cp == '-') 62: switch (smatch (++cp, switches)) { 63: case AMBIGSW: 64: ambigsw (cp, switches); 65: done (1); 66: case UNKWNSW: 67: adios (NULLCP, "-%s unknown", cp); 68: case HELPSW: 69: (void) sprintf (buf, "%s [+folder] [switches]", invo_name); 70: help (buf, switches); 71: done (1); 72: 73: case INTRSW: 74: interactive = 1; 75: continue; 76: case NINTRSW: 77: interactive = 0; 78: continue; 79: } 80: if (*cp == '+' || *cp == '@') { 81: if (folder) 82: adios (NULLCP, "only one folder at a time!"); 83: else 84: folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); 85: } 86: else 87: adios (NULLCP, "usage: %s [+folder] [switches]", invo_name); 88: } 89: 90: /* */ 91: 92: if (!m_find ("path")) 93: free (path ("./", TFOLDER)); 94: if (!folder) { 95: folder = m_getfolder (); 96: defolder++; 97: } 98: if (strcmp (m_mailpath (folder), pwd ()) == 0) 99: adios (NULLCP, "sorry, you can't remove the current working directory"); 100: 101: if (interactive == -1) 102: interactive = defolder; 103: 104: if (index (folder, '/') && (*folder != '/') && (*folder != '.')) { 105: for (cp = copy (folder, newfolder); cp > newfolder && *cp != '/'; cp--) 106: continue; 107: if (cp > newfolder) 108: *cp = NULL; 109: else 110: (void) strcpy (newfolder, defalt); 111: } 112: else 113: (void) strcpy (newfolder, defalt); 114: 115: if (interactive) { 116: cp = concat ("Remove folder \"", folder, "\"? ", NULLCP); 117: if (!getanswer (cp)) 118: done (0); 119: free (cp); 120: } 121: 122: if (rmf (folder) == OK && strcmp (m_find (pfolder), newfolder)) { 123: printf ("[+%s now current]\n", newfolder); 124: m_replace (pfolder, newfolder); 125: } 126: m_update (); 127: 128: done (0); 129: } 130: 131: /* */ 132: 133: static int rmf (folder) 134: register char *folder; 135: { 136: int i, 137: j, 138: others; 139: register char *maildir; 140: char cur[BUFSIZ]; 141: register struct direct *dp; 142: register DIR * dd; 143: 144: #ifdef COMPAT 145: (void) m_delete (concat (current, "-", m_mailpath (folder), NULLCP)); 146: #endif COMPAT 147: switch (i = chdir (maildir = m_maildir (folder))) { 148: case OK: 149: if (access (".", 2) != NOTOK && access ("..", 2) != NOTOK) 150: break; /* fall otherwise */ 151: 152: case NOTOK: 153: (void) sprintf (cur, "atr-%s-%s", current, m_mailpath (folder)); 154: if (!m_delete (cur)) { 155: printf ("[+%s de-referenced]\n", folder); 156: return OK; 157: } 158: advise (NULLCP, "you have no profile entry for the %s folder +%s", 159: i == NOTOK ? "unreadable" : "read-only", folder); 160: return NOTOK; 161: } 162: 163: if ((dd = opendir (".")) == NULL) 164: adios (NULLCP, "unable to read folder +%s", folder); 165: others = 0; 166: 167: j = strlen (SBACKUP); 168: while (dp = readdir (dd)) { 169: switch (dp -> d_name[0]) { 170: case '.': 171: if (strcmp (dp -> d_name, ".") == 0 172: || strcmp (dp -> d_name, "..") == 0) 173: continue; /* else fall */ 174: 175: case ',': 176: #ifdef MHE 177: case '+': 178: #endif MHE 179: #ifdef UCI 180: case '_': 181: case '#': 182: #endif UCI 183: break; 184: 185: default: 186: if (m_atoi (dp -> d_name)) 187: break; 188: #ifdef COMPAT 189: if (strcmp (dp -> d_name, current) == 0) 190: break; 191: #endif COMPAT 192: if (strcmp (dp -> d_name, LINK) == 0 193: || strncmp (dp -> d_name, SBACKUP, j) == 0) 194: break; 195: 196: admonish (NULLCP, "file \"%s/%s\" not deleted", 197: folder, dp -> d_name); 198: others++; 199: continue; 200: } 201: if (unlink (dp -> d_name) == NOTOK) { 202: admonish (dp -> d_name, "unable to unlink %s:", folder); 203: others++; 204: } 205: } 206: 207: closedir (dd); 208: 209: rma (folder); 210: 211: (void) chdir (".."); 212: if (others == 0 && remdir (maildir)) 213: return OK; 214: 215: advise (NULLCP, "folder +%s not removed", folder); 216: return NOTOK; 217: } 218: 219: /* */ 220: 221: static rma (folder) 222: register char *folder; 223: { 224: register int alen, 225: j, 226: plen; 227: register char *cp; 228: register struct node *np, 229: *pp; 230: 231: alen = strlen ("atr-"); 232: plen = strlen (cp = m_mailpath (folder)) + 1; 233: 234: m_getdefs (); 235: for (np = m_defs, pp = NULL; np; np = np -> n_next) 236: if (ssequal ("atr-", np -> n_name) 237: && (j = strlen (np -> n_name) - plen) > alen 238: && *(np -> n_name + j) == '-' 239: && strcmp (cp, np -> n_name + j + 1) == 0) { 240: if (!np -> n_context) 241: admonish (NULLCP, "bug: m_delete(key=\"%s\")", np -> n_name); 242: if (pp) { 243: pp -> n_next = np -> n_next; 244: np = pp; 245: } 246: else 247: m_defs = np -> n_next; 248: ctxflags |= CTXMOD; 249: } 250: else 251: pp = np; 252: }