void MsgStorage::userdir_open(string domain, string user, AmArg& ret) { // TODO: block the directory from delete (increase lock) string path = msg_dir + "/" + domain + "/" + user + "/"; DBG("trying to list '%s'\n", path.c_str()); DIR* dir = opendir(path.c_str()); if (!dir) { ret.push(MSG_EUSRNOTFOUND); ret.push(AmArg()); // empty list return; } int err=0; struct dirent* entry; AmArg msglist; msglist.assertArray(0); // make it an array while( ((entry = readdir(dir)) != NULL) && (err == 0) ){ string msgname(entry->d_name); if(!msgname.length() || msgname[0] == '.'){ continue; } struct stat e_stat; if (stat((path+msgname).c_str(), &e_stat)) { ERROR("cannot stat '%s': %s\n", (path+msgname).c_str(),strerror(errno)); continue; } AmArg msg; msg.push(msgname.c_str()); // TODO: change the system here, st_atime/mtime/... // is not really safe for saving read status! if (e_stat.st_atime != e_stat.st_mtime) { msg.push(0); } else { msg.push(1); } msg.push((int)e_stat.st_size); msglist.push(msg); } closedir(dir); // uh, this is really inefficient... ret.push(MSG_OK); ret.push(msglist); }
int msggetmask(char* buf, register int n, register unsigned long mask) { register char* b; register const char* s; register int m; register int n0; register int n1; char* e; if (n <= 1) return 0; if (b = buf) e = b + n; for (n0 = n1 = 0, m = 1; m <= MSG_STD; m++) { n = strlen(msgname(m)) + 1; if (mask & MSG_MASK(m)) n1 += n; else n0 += n; } if (n = (n1 > n0)) { n0++; if (!b) return n0; n0 = -n0; if (b >= e) return n0; *b++ = '!'; } else if (!b) return n1; else n0 = -n1; for (m = 1; m <= MSG_STD; m++) if ((mask & MSG_MASK(m)) == 0 == n) { s = msg_info.name[m]; while (n1 = *s++) { if (b >= e) return n0; *b++ = n1; } if (b >= e) return n0; *b++ = ','; } if (b > buf && *(b - 1) == ',') b--; *b = 0; return b - buf; }