order.c
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:3k
源码类别:

P2P编程

开发平台:

Visual C++

  1. /*
  2.  *  Openmysee
  3.  *
  4.  *  This program is free software; you can redistribute it and/or modify
  5.  *  it under the terms of the GNU General Public License as published by
  6.  *  the Free Software Foundation; either version 2 of the License, or
  7.  *  (at your option) any later version.
  8.  *
  9.  *  This program is distributed in the hope that it will be useful,
  10.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *  GNU General Public License for more details.
  13.  *
  14.  *  You should have received a copy of the GNU General Public License
  15.  *  along with this program; if not, write to the Free Software
  16.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17.  *
  18.  */
  19.  
  20. #include "echo.h"
  21. static int NumNewOrder;
  22. static struct Channel *OrderHash[MAX_CHANNEL];
  23. static struct Channel *OrderList;
  24. extern char *PREFIX;
  25. static inline void buildOrderPath (char *buf, int len, char *md5)
  26. {
  27. snprintf (buf, len, "%s/%s/%.2s/", PREFIX, ORDER_PREFIX, md5);
  28. mkdir (buf, 0777);
  29. strcat (buf, md5);
  30. }
  31. /* DB format: MD5->[file_size(int)][filename_size(int)]filename */
  32. static FILE *openOrder (char *md5, off_t *size)
  33. {
  34. struct stat statbuf;
  35. char fname[MAX_DATA];
  36. if (*md5 == 0)
  37. return NULL;
  38. buildOrderPath (fname, CHNLURL_LEN, md5);
  39. if (stat (fname, &statbuf) != 0)
  40. return NULL;
  41. *size = statbuf.st_size;
  42. return fopen (fname, "r");
  43. }
  44. struct Channel *newOrder (char *md5)
  45. {
  46. int i, id;
  47. off_t size;
  48. FILE *db;
  49. struct Channel *p, *q;
  50. if ((db=openOrder (md5, &size)) == NULL)
  51. return NULL;
  52. if (NumNewOrder >= MAX_CHANNEL)
  53. {
  54. for (i=0; i<MAX_CHANNEL; i++)
  55. {
  56. for (p=OrderHash[i]; p; p=p->next)
  57. {
  58. if (p->numjob == 0)
  59. break;
  60. }
  61. if (p) break;
  62. }
  63. if (!p) return (struct Channel *)0;
  64. if (OrderHash[i] == p)
  65. {
  66. OrderHash[i] = NULL;
  67. } else
  68. {
  69. for (q=OrderHash[i]; q && q->next != p; q=q->next);
  70. assert (q);
  71. q->next = p->next;
  72. }
  73. if (p->db) fclose (p->db);
  74. } else
  75. {
  76. NumNewOrder ++;
  77. p = (struct Channel *)calloc (sizeof (struct Channel), 1);
  78. }
  79. memcpy (p->channel_md5, md5, MD5_LEN);
  80. p->maxblocksize = DEFAULT_BLOCK;
  81. p->pcinfo = NULL;
  82. id = hash_str (p->channel_md5, MD5_LEN);
  83. PDEBUG("newOrder hash %.32s to %d.n", p->channel_md5, id);
  84. p->downsize = size;
  85. p->upsize = 0;
  86. p->db = db;
  87. p->next = OrderHash[id];
  88. OrderHash[id] = p;
  89. p->lnext = OrderList;
  90. OrderList = p;
  91. return p;
  92. }
  93. int locate_order_by_id (struct Channel *c, uint32_t id, char *buf, int max)
  94. {
  95. long long size;
  96. assert (buf && c);
  97. if ((size = c->downsize - id*DEFAULT_BLOCK) >= DEFAULT_BLOCK)
  98. size = DEFAULT_BLOCK;
  99. else if (size <= 0)
  100. {
  101. return -1;
  102. }
  103. if (max <= size) return -2;
  104. if (fseeko (c->db, ((off_t)DEFAULT_BLOCK)*((off_t)id), SEEK_SET) != 0)
  105. {
  106. PDEBUG ("fseek failed.n");
  107. return -1;
  108. }
  109. if (fread (buf, size, 1, c->db) == 1)
  110. {
  111. c->upsize += size;
  112. return size;
  113. }
  114. return -1;
  115. }
  116. struct Channel *findOrder (char *name, int len)
  117. {
  118. return getChannel (OrderHash, name, len);
  119. }
  120. void freeOrder (struct Channel *pc, void *p)
  121. {
  122. freeChannel (OrderHash, &OrderList, &NumNewOrder, pc);
  123. }
  124. void freeAllOrder ()
  125. {
  126. apply_hash (OrderHash, freeOrder, NULL);
  127. }