db.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include "all.h"
  2. static Entry *fe;
  3. static Entry*
  4. allocentry(void)
  5. {
  6. int i;
  7. Entry *e;
  8. if(fe == nil){
  9. fe = emalloc(128*sizeof(Entry));
  10. for(i=0; i<128-1; i++)
  11. fe[i].name = (char*)&fe[i+1];
  12. fe[i].name = nil;
  13. }
  14. e = fe;
  15. fe = (Entry*)e->name;
  16. memset(e, 0, sizeof *e);
  17. return e;
  18. }
  19. static void
  20. freeentry(Entry *e)
  21. {
  22. e->name = (char*)fe;
  23. fe = e;
  24. }
  25. static void
  26. _removedb(Db *db, char *name)
  27. {
  28. Entry *e, k;
  29. memset(&k, 0, sizeof k);
  30. k.name = name;
  31. e = nil;
  32. deleteavl(db->avl, (Avl*)&k, (Avl**)&e);
  33. if(e)
  34. freeentry(e);
  35. }
  36. static void
  37. _insertdb(Db *db, Entry *e)
  38. {
  39. Entry *o, *ne;
  40. ne = allocentry();
  41. *ne = *e;
  42. o = nil;
  43. insertavl(db->avl, (Avl*)ne, (Avl**)&o);
  44. if(o)
  45. freeentry(o);
  46. }
  47. static int
  48. entrycmp(Avl *a, Avl *b)
  49. {
  50. Entry *ea, *eb;
  51. ea = (Entry*)a;
  52. eb = (Entry*)b;
  53. return strcmp(ea->name, eb->name);
  54. }
  55. Db*
  56. opendb(char *file)
  57. {
  58. char *f[10], *s, *t;
  59. int i, fd, nf;
  60. Biobuf b;
  61. Db *db;
  62. Entry e;
  63. if(file == nil)
  64. fd = -1;
  65. else if((fd = open(file, ORDWR)) < 0)
  66. sysfatal("opendb %s: %r", file);
  67. db = emalloc(sizeof(Db));
  68. db->avl = mkavltree(entrycmp);
  69. db->fd = fd;
  70. if(fd < 0)
  71. return db;
  72. Binit(&b, fd, OREAD);
  73. i = 0;
  74. for(; s=Brdstr(&b, '\n', 1); free(s)){
  75. t = estrdup(s);
  76. nf = tokenize(s, f, nelem(f));
  77. if(nf != 7)
  78. sysfatal("bad database entry '%s'", t);
  79. free(t);
  80. if(strcmp(f[2], "REMOVED") == 0)
  81. _removedb(db, f[0]);
  82. else{
  83. memset(&e, 0, sizeof e);
  84. e.name = atom(f[0]);
  85. e.d.name = atom(f[1]);
  86. if(strcmp(e.d.name, "-")==0)
  87. e.d.name = e.name;
  88. e.d.mode = strtoul(f[2], 0, 8);
  89. e.d.uid = atom(f[3]);
  90. e.d.gid = atom(f[4]);
  91. e.d.mtime = strtoul(f[5], 0, 10);
  92. e.d.length = strtoll(f[6], 0, 10);
  93. _insertdb(db, &e);
  94. i++;
  95. }
  96. }
  97. return db;
  98. }
  99. static int
  100. _finddb(Db *db, char *name, Dir *d, int domark)
  101. {
  102. Entry *e, k;
  103. memset(&k, 0, sizeof k);
  104. k.name = name;
  105. e = (Entry*)lookupavl(db->avl, (Avl*)&k);
  106. if(e == nil)
  107. return -1;
  108. memset(d, 0, sizeof *d);
  109. d->name = e->d.name;
  110. d->uid = e->d.uid;
  111. d->gid = e->d.gid;
  112. d->mtime = e->d.mtime;
  113. d->mode = e->d.mode;
  114. d->length = e->d.length;
  115. if(domark)
  116. e->d.mark = 1;
  117. return 0;
  118. }
  119. int
  120. finddb(Db *db, char *name, Dir *d)
  121. {
  122. return _finddb(db, name, d, 0);
  123. }
  124. int
  125. markdb(Db *db, char *name, Dir *d)
  126. {
  127. return _finddb(db, name, d, 1);
  128. }
  129. void
  130. removedb(Db *db, char *name)
  131. {
  132. if(db->fd>=0 && fprint(db->fd, "%q xxx REMOVED xxx xxx 0 0\n", name) < 0)
  133. sysfatal("appending to db: %r");
  134. _removedb(db, name);
  135. }
  136. void
  137. insertdb(Db *db, char *name, Dir *d)
  138. {
  139. char *dname;
  140. Entry e;
  141. memset(&e, 0, sizeof e);
  142. e.name = atom(name);
  143. e.d.name = atom(d->name);
  144. e.d.uid = atom(d->uid);
  145. e.d.gid = atom(d->gid);
  146. e.d.mtime = d->mtime;
  147. e.d.mode = d->mode;
  148. e.d.length = d->length;
  149. e.d.mark = d->muid!=0;
  150. dname = d->name;
  151. if(strcmp(name, dname) == 0)
  152. dname = "-";
  153. if(db->fd>=0 && fprint(db->fd, "%q %q %luo %q %q %lud %lld\n", name, dname, d->mode, d->uid, d->gid, d->mtime, d->length) < 0)
  154. sysfatal("appending to db: %r");
  155. _insertdb(db, &e);
  156. }