db.c 3.4 KB

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