📄 order.c
字号:
/*
* Openmysee
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "echo.h"
static int NumNewOrder;
static struct Channel *OrderHash[MAX_CHANNEL];
static struct Channel *OrderList;
extern char *PREFIX;
static inline void buildOrderPath (char *buf, int len, char *md5)
{
snprintf (buf, len, "%s/%s/%.2s/", PREFIX, ORDER_PREFIX, md5);
mkdir (buf, 0777);
strcat (buf, md5);
}
/* DB format: MD5->[file_size(int)][filename_size(int)]filename */
static FILE *openOrder (char *md5, off_t *size)
{
struct stat statbuf;
char fname[MAX_DATA];
if (*md5 == 0)
return NULL;
buildOrderPath (fname, CHNLURL_LEN, md5);
if (stat (fname, &statbuf) != 0)
return NULL;
*size = statbuf.st_size;
return fopen (fname, "r");
}
struct Channel *newOrder (char *md5)
{
int i, id;
off_t size;
FILE *db;
struct Channel *p, *q;
if ((db=openOrder (md5, &size)) == NULL)
return NULL;
if (NumNewOrder >= MAX_CHANNEL)
{
for (i=0; i<MAX_CHANNEL; i++)
{
for (p=OrderHash[i]; p; p=p->next)
{
if (p->numjob == 0)
break;
}
if (p) break;
}
if (!p) return (struct Channel *)0;
if (OrderHash[i] == p)
{
OrderHash[i] = NULL;
} else
{
for (q=OrderHash[i]; q && q->next != p; q=q->next);
assert (q);
q->next = p->next;
}
if (p->db) fclose (p->db);
} else
{
NumNewOrder ++;
p = (struct Channel *)calloc (sizeof (struct Channel), 1);
}
memcpy (p->channel_md5, md5, MD5_LEN);
p->maxblocksize = DEFAULT_BLOCK;
p->pcinfo = NULL;
id = hash_str (p->channel_md5, MD5_LEN);
PDEBUG("newOrder hash %.32s to %d.\n", p->channel_md5, id);
p->downsize = size;
p->upsize = 0;
p->db = db;
p->next = OrderHash[id];
OrderHash[id] = p;
p->lnext = OrderList;
OrderList = p;
return p;
}
int locate_order_by_id (struct Channel *c, uint32_t id, char *buf, int max)
{
long long size;
assert (buf && c);
if ((size = c->downsize - id*DEFAULT_BLOCK) >= DEFAULT_BLOCK)
size = DEFAULT_BLOCK;
else if (size <= 0)
{
return -1;
}
if (max <= size) return -2;
if (fseeko (c->db, ((off_t)DEFAULT_BLOCK)*((off_t)id), SEEK_SET) != 0)
{
PDEBUG ("fseek failed.\n");
return -1;
}
if (fread (buf, size, 1, c->db) == 1)
{
c->upsize += size;
return size;
}
return -1;
}
struct Channel *findOrder (char *name, int len)
{
return getChannel (OrderHash, name, len);
}
void freeOrder (struct Channel *pc, void *p)
{
freeChannel (OrderHash, &OrderList, &NumNewOrder, pc);
}
void freeAllOrder ()
{
apply_hash (OrderHash, freeOrder, NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -