dirread.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <fcall.h>
  4. static
  5. long
  6. dirpackage(uchar *buf, long ts, Dir **d)
  7. {
  8. char *s;
  9. long ss, i, n, nn, m;
  10. *d = nil;
  11. if(ts <= 0)
  12. return 0;
  13. /*
  14. * first find number of all stats, check they look like stats, & size all associated strings
  15. */
  16. ss = 0;
  17. n = 0;
  18. for(i = 0; i < ts; i += m){
  19. m = BIT16SZ + GBIT16(&buf[i]);
  20. if(statcheck(&buf[i], m) < 0)
  21. break;
  22. ss += m;
  23. n++;
  24. }
  25. if(i != ts)
  26. return -1;
  27. *d = malloc(n * sizeof(Dir) + ss);
  28. if(*d == nil)
  29. return -1;
  30. /*
  31. * then convert all buffers
  32. */
  33. s = (char*)*d + n * sizeof(Dir);
  34. nn = 0;
  35. for(i = 0; i < ts; i += m){
  36. m = BIT16SZ + GBIT16((uchar*)&buf[i]);
  37. if(nn >= n || convM2D(&buf[i], m, *d + nn, s) != m){
  38. free(*d);
  39. *d = nil;
  40. return -1;
  41. }
  42. nn++;
  43. s += m;
  44. }
  45. return nn;
  46. }
  47. long
  48. dirread(int fd, Dir **d)
  49. {
  50. uchar *buf;
  51. long ts;
  52. buf = malloc(DIRMAX);
  53. if(buf == nil)
  54. return -1;
  55. ts = read(fd, buf, DIRMAX);
  56. if(ts >= 0)
  57. ts = dirpackage(buf, ts, d);
  58. free(buf);
  59. return ts;
  60. }
  61. long
  62. dirreadall(int fd, Dir **d)
  63. {
  64. uchar *buf, *nbuf;
  65. long n, ts;
  66. buf = nil;
  67. ts = 0;
  68. for(;;){
  69. nbuf = realloc(buf, ts+DIRMAX);
  70. if(nbuf == nil){
  71. free(buf);
  72. return -1;
  73. }
  74. buf = nbuf;
  75. n = read(fd, buf+ts, DIRMAX);
  76. if(n <= 0)
  77. break;
  78. ts += n;
  79. }
  80. if(ts >= 0)
  81. ts = dirpackage(buf, ts, d);
  82. free(buf);
  83. if(ts == 0 && n < 0)
  84. return -1;
  85. return ts;
  86. }