⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 group.c

📁 chord 源码 http://pdos.csail.mit.edu/chord/
💻 C
字号:
#include <rxx.h>#include <wmstr.h>#include <dbfe.h>#include <group.h>#include <usenet.h>boolvalid_group_name (str g){  static rxx dot ("\\.");  strbuf vgnlog;  vgnlog << "valid_group_name (" << g << "): ";  // XXX this check could probably be done entirely using a regex  // http://www.eyrie.org/~eagle/faqs/big-eight.html  // A group name is made up of name components separated by '.' (period or  // dot). Each component must consist solely of lowercase ASCII letters,  // digits, '+' (plus), or '-' (dash), must contain at least one letter (a-z),  // and must be no more than twenty characters long.  vec<str> components;  int n = split (&components, dot, g, (size_t) -1, true);  if (n == 1) {    warnx << vgnlog << "too few components!\n";    return false;  }  for (size_t i = 0; i < components.size (); i++) {    if (components[i].len () > 20) {      vgnlog << "component " << i << " too long.\n";      return false;    }    if (components[i].len () == 0) {      vgnlog << "component " << i << " too short.\n";      return false;    }    bool onechar (false);    for (size_t j = 0; j < components[i].len (); j++) {      register int c = components[i][j];      if (islower (c))	onechar = true;      if (! (islower (c) || isdigit (c) || (c == '-') || (c == '+'))) {	warnx << vgnlog << "bad char " << i << "," << j << ": "	      << components[i][j] << ".\n";	return false;      }    }    if (!onechar) {      warnx << vgnlog << "no characters in component " << i << ".\n";      return false;    }  }  return true;}boolcreate_group (const char *group){  static ptr<dbrec> d (NULL);  if (!d) {    group_entry g;    str m = xdr2str (g);    d = New refcounted<dbrec> (m, m.len ());  }  if (!valid_group_name (group))    return false;  ref<dbrec> k = New refcounted<dbrec> (group, strlen (group));  group_db->insert (k, d);  return true;}grouplist::grouplist (){  it = group_db->enumerate();  d = it->nextElement();    }voidgrouplist::next (str *f, unsigned long *i){  *f = str (d->key->value, d->key->len);  ptr<dbrec> rec = group_db->lookup (d->key);  xdrmem x (rec->value, rec->len, XDR_DECODE);  group_entry *group = New group_entry;  bzero (group, sizeof (*group));  if (xdr_group_entry (x.xdrp (), group)) {    *i = group->articles.size () ;    xdr_delete (reinterpret_cast<xdrproc_t> (xdr_group_entry), group);  } else {    *i = 0;    delete group;  }  d = it->nextElement();}newsgroup::newsgroup () :  group (NULL),  start (0),  stop (0),  next_idx (0),  group_name_rec (NULL),  cur_art (0){}newsgroup::~newsgroup () {  if (group) {    xdr_delete (reinterpret_cast<xdrproc_t> (xdr_group_entry), group);    group = NULL;  }}group_entry *newsgroup::load (ptr<dbrec> g){  ptr<dbrec> rec (NULL);  rec = group_db->lookup (g);  if (rec == NULL)    return NULL;   xdrmem x (rec->value, rec->len, XDR_DECODE);  group_entry *group = New group_entry;  bzero (group, sizeof (*group));  if (xdr_group_entry (x.xdrp (), group))     return group;  xdr_delete (reinterpret_cast<xdrproc_t> (xdr_group_entry), group);  group = NULL;  return NULL;}intnewsgroup::open (str g){  ptr<dbrec> gn = New refcounted<dbrec> (g, g.len ());  if (group) {    xdr_delete (reinterpret_cast<xdrproc_t> (xdr_group_entry), group);    group = NULL;  }  group = load (gn);  if (group == NULL)    return -1;  group_name = g;  group_name_rec = gn;  cur_art = 1;  return 0;}intnewsgroup::open (str g, unsigned long *count,	         unsigned long *first, unsigned long *last){  if (open (g) < 0)    return -1;  *count = 0;  *first = 0;  *last  = 0;  // Find the first and last article numbers and also  // how many articles there are.  *count = group->articles.size ();  if (*count > 0) {    *first = group->articles[0].artno;    *last  = group->articles[*count - 1].artno;  }  return 0;}voidnewsgroup::addid (str msgid, chordID ID){  // Must get a new copy of data from disk in case of  // other "simultaneous" connections.  if (group) {    xdr_delete (reinterpret_cast<xdrproc_t> (xdr_group_entry), group);    group = NULL;  }  group = load (group_name_rec);  if (!group) {    warn << "newsgroup::addid: load failed\n";    return;  }  // Find next article number   u_int32_t article_count = group->articles.size ();   u_int32_t lastno = 0;  if (article_count > 0)    lastno = group->articles[article_count - 1].artno;  // Add new article to cached listing  article_mapping nart;  nart.artno = lastno + 1;  nart.msgid = msgid;  nart.blkid = ID;  group->articles.push_back (nart);  // Marshal listing  xdrsuio x (XDR_ENCODE);  if (!xdr_group_entry (x.xdrp (), group)) {    warn << "newsgroup::addid: marshalling failed\n";    return;  }  mstr m (x.uio ()->resid ());  x.uio ()->copyout (m);  // And schedule a write.  ptr<dbrec> rec = New refcounted<dbrec> (m, m.len ());  group_db->insert (group_name_rec, rec);}// now returns the chordidchordIDnewsgroup::getid (unsigned long index){  if (!loaded ())    return 0;  for (size_t i = 0; i < group->articles.size (); i++) {    if (index == group->articles[i].artno)      return group->articles[i].blkid;    else if (group->articles[i].artno > index)      return 0;  }  return 0;}static rxx getchordid ("^X-ChordID: (.+)$", "m");chordIDnewsgroup::getid (str msgid){  ptr<dbrec> key, d;  key = New refcounted<dbrec> (msgid, msgid.len ());  d = header_db->lookup (key);  if (d && getchordid.search (str (d->value, d->len)))    return bigint (getchordid[1], 16);  else    return 0;}voidnewsgroup::xover (unsigned long a, unsigned long b){  assert (loaded ());  start = a;  stop = b;  for (next_idx = 0; next_idx < group->articles.size (); next_idx++)    if (group->articles[next_idx].artno >= start)      break;}boolnewsgroup::more (){   return start < stop && next_idx < group->articles.size ();}static rxx oversub ("Subject: (.+)\\r");static rxx overfrom ("From: (.+)\\r");static rxx overdate ("Date: (.+)\\r");static rxx overmsgid ("Message-ID: (.+)\\r");static rxx overref ("References: (.+)\\r");static rxx overlines ("X-Lines: (.+)\\r");static strtabfilter (str f){  mstr out (f.len ());  char *d = out;  for (unsigned int i = 0; i < f.len (); i++) {    d[i] = f[i];    if (d[i] == '\t')      d[i] = ' ';  }  return out;}// format: "subject\tauthor\tdate\t<msgid>\treferences\tsize\tlines"strbufnewsgroup::next (void){  ptr<dbrec> art (NULL);  article_mapping m;  strbuf resp;  while (more () && art == NULL)  {    m = group->articles[next_idx];    ptr<dbrec> k = New refcounted<dbrec> (m.msgid.cstr (), m.msgid.len ());    next_idx++;    art = header_db->lookup (k);    if (art == NULL)      warn << "newsgroup::next: missing article " << start << "\n";    start++;  }      if (art == NULL)    return resp;    str msg (art->value, art->len);    // XXX should parse this once only.  if (oversub.search (msg) &&      overfrom.search (msg) &&      overdate.search (msg)) {    resp << start - 1 << "\t";    resp << tabfilter (oversub[1]) << "\t" 	 << tabfilter (overfrom[1]) << "\t";    resp << tabfilter (overdate[1]) << "\t";        if (overmsgid.search (msg))      resp << tabfilter (overmsgid[1]) << "\t";    else      resp << tabfilter (m.msgid) << "\t";    if (overref.search (msg))      resp << tabfilter (overref[1]);    resp << "\t" << art->len << "\t";    if (overlines.search (msg))      resp << tabfilter (overlines[1]);    else      resp << "0";    resp << "\t\r\n";  } else {    warn << "msg parse error\n";    warn << "msg " << m.msgid << "\n";    warn << "header " << msg << "\n";  }    return resp;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -