program.c
资源名称:p2p_vod.rar [点击查看]
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:9k
源码类别:
P2P编程
开发平台:
Visual 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"
- extern time_t CurrentTime;
- extern char *PREFIX;
- static struct Channel *ProgramHash[MAX_CHANNEL];
- static struct Channel *ProgramList;
- static int NumNewProg;
- static struct Channel *findProgram (char *name, int len)
- {
- return getChannel (ProgramHash, name, len);
- }
- #define skipSeparator(ptr,end) do
- {
- while ((*ptr == '=' || isspace (*ptr)) && ptr < end) ptr ++;
- } while (0)
- #define skipSpace(ptr,end) do
- {
- while (isspace (*ptr) && ptr < end) ptr ++;
- } while (0)
- #define skipNonalnum(ptr,end) do
- {
- while ((!isalnum (*ptr)) && ptr < end) ptr ++;
- } while (0)
- #define lineup(ptr,end) do
- {
- while (*ptr != 'r' && *ptr != 'n' && ptr < end) ptr ++;
- } while (0)
- #define copyStr(src,dst,max,end) do
- {
- while ((!isspace (*ptr)) && max >= 0 && ptr < end)
- {
- *dst++ = *src++;
- max --;
- }
- *dst = 0;
- } while (0)
- static int read_prog_config (char *name, char *cname, int maxlen, float *bitrate, int *bsize, int *datalen, char **data)
- {
- int len, size;
- FILE *in;
- char *buffer=NULL, *ptr, *end;
- char *p, *dst;
- struct stat stbuf;
- if (stat (name, &stbuf) != 0 || !(S_ISREG (stbuf.st_mode)))
- {
- PDEBUG ("Config file %s does not exist.n", name);
- return -1;
- }
- if ((in=fopen (name, "r")) == NULL)
- {
- PDEBUG ("Cannot open file %sn", name);
- return -1;
- }
- size = stbuf.st_size;
- buffer = calloc (1, size+1);
- if (fread (buffer, size, 1, in) != 1)
- {
- PDEBUG ("Cannot read all the file %s.n", name);
- fclose (in);
- free (buffer);
- return -1;
- }
- end = buffer + size + 1;
- for (ptr=buffer; ptr<end;)
- {
- skipSpace (ptr, end);
- if (strncasecmp (ptr, "ChannelName", strlen ("ChannelName")) == 0)
- {
- ptr += strlen ("ChannelName");
- if (isalnum (*ptr))
- {
- lineup (ptr,end);
- continue;
- }
- skipSeparator(ptr,end);
- if (ptr >= end) break;
- copyStr (ptr, cname, maxlen,end);
- lineup (ptr,end);
- }
- else if (strncasecmp (ptr, "BitRate", strlen ("BitRate")) == 0)
- {
- ptr += strlen ("BitRate");
- if (isalnum (*ptr)) lineup (ptr,end);
- skipNonalnum (ptr,end);
- if (ptr >= end) break;
- *bitrate = atof (ptr);
- lineup (ptr,end);
- }
- else if (strncasecmp (ptr, "BlockSize", strlen ("BlockSize")) == 0)
- {
- ptr += strlen ("BlockSize");
- if (isalnum (*ptr)) lineup (ptr,end);
- skipNonalnum (ptr,end);
- if (ptr >= end) break;
- *bsize = atoi (ptr);
- lineup (ptr,end);
- }
- else if (strncasecmp (ptr, "DataLength", strlen ("DataLength")) == 0)
- {
- ptr += strlen ("DataLength");
- if (isalnum (*ptr)) lineup (ptr,end);
- skipNonalnum (ptr,end);
- if (ptr >= end) break;
- *datalen = atoi (ptr);
- lineup (ptr,end);
- }
- else if (strncasecmp (ptr, "Data", strlen ("Data")) == 0)
- {
- ptr += strlen ("Data=");
- len = *datalen;
- if (ptr >= end) break;
- dst = p = calloc (1, len+1);
- while (len >= 0)
- {
- *p++ = *ptr++;
- len --;
- }
- *data = dst;
- lineup (ptr,end);
- }
- else
- {
- lineup (ptr,end);
- }
- }
- fclose (in);
- if (buffer != NULL) free (buffer);
- return 0;
- }
- static inline void buildProgPath (char *buf, int len, char *md5)
- {
- snprintf (buf, len, "%s/%s/", PREFIX, PROG_PREFIX);
- strcat (buf, md5);
- }
- // Return 1 to indicate write available, return 0 to indicate now writable.
- static inline int newPListChannelFile (struct Channel *p)
- {
- struct stat stbuf;
- char buffer[MAX_LINE];
- struct LiveChannelInfo *pcinfo = p->pcinfo;
- if (pcinfo->numinput >= MAX_FILEINPUT)
- {
- PDEBUG ("Max file input has been reached, %s:%d.n", p->fname,pcinfo->numinput);
- return -1;
- }
- snprintf (buffer, MAX_LINE, "%s/%d", p->fname, pcinfo->numinput);
- if (stat (buffer, &stbuf) == 0 && (pcinfo->input[pcinfo->numinput] = fopen (buffer, "r")) != NULL)
- {
- pcinfo->maxID += stbuf.st_size / p->maxblocksize;
- pcinfo->numinput ++;
- return 0;
- }
- return -1;
- }
- static int init_prog (struct Channel *p)
- {
- int i;
- struct stat stbuf;
- char buffer[MAX_LINE];
- struct LiveChannelInfo *pcinfo = p->pcinfo;
- if (p->maxblocksize == 0) p->maxblocksize = DEFAULT_BLOCK;
- while ((i = newPListChannelFile (p)) == 0);
- pcinfo->max_queue = BLOCK_PER_FILE;
- snprintf (buffer, MAX_LINE, "%s/keysample", p->fname);
- if (stat (buffer, &stbuf) == 0)
- {
- if (!S_ISREG (stbuf.st_mode))
- {
- PDEBUG ("File %s exist and not a regular file", buffer);
- return -1;
- }
- }
- pcinfo->keyfile = fopen (buffer, "r");
- if (pcinfo->keyfile == NULL)
- {
- PDEBUG ("File %s can not be opened.n", buffer);
- return -1;
- }
- pcinfo->total = 0;
- pcinfo->isSave = 1;
- // timer_add (CurrentTime, (TimerFunc)send_spupdate, p, NULL);
- return 0;
- }
- static struct Channel *newProg (char *name, struct Session *source, char *cmd5, float bitrate, int maxblocksize)
- {
- int id;
- struct Channel *p;
- struct LiveChannelInfo *pcinfo;
- if (NumNewProg >= MAX_CHANNEL) return (struct Channel *)0;
- p = (struct Channel *)calloc (sizeof (struct Channel), 1);
- memcpy (p->channel_md5, cmd5, MD5_LEN);
- if (name) strncpy (p->channel_name, name, sizeof (p->channel_name));
- p->channel_md5[MD5_LEN] = 0;
- p->upsize = 0;
- p->downsize = 0;
- p->maxblocksize = maxblocksize;
- p->ctime = time (NULL);
- p->pcinfo = (struct LiveChannelInfo *)calloc (sizeof (struct LiveChannelInfo), 1);
- pcinfo = p->pcinfo;
- pcinfo->dataSource = source;
- pcinfo->bitrate = bitrate;
- buildProgPath (p->fname, CHNLURL_LEN, cmd5);
- if (init_prog (p) < 0)
- {
- PDEBUG ("newPlistChannel error for %p.", p);
- free_livechannel (p);
- free (pcinfo);
- free (p);
- return (struct Channel *)0;
- }
- id = hash_str (p->channel_md5, MD5_LEN);
- PDEBUG("newPlistChannel hash %.32s(fname=%s) to %d.n", p->channel_md5, p->fname, id);
- p->next = ProgramHash[id];
- ProgramHash[id] = p;
- p->lnext = ProgramList;
- ProgramList = p;
- NumNewProg ++;
- return p;
- }
- static struct Channel *add_prog (char *buffer, char *md5)
- {
- struct stat stbuf;
- struct Channel *pc=NULL;
- char *data=NULL, cname[MAX_DATA];
- float bitrate=0.0;
- int bsize=16384, dlen=0;
- if (stat (buffer, &stbuf) < 0) return NULL;
- if (!S_ISDIR (stbuf.st_mode))
- return NULL;
- else
- {
- strcat (buffer, "/config");
- if (read_prog_config (buffer, cname, sizeof(cname), &bitrate, &bsize, &dlen, &data) < 0)
- {
- PDEBUG ("Error in parse file %s.n", buffer);
- return NULL;
- }
- if ((pc=newProg (cname, NULL, md5, bitrate, bsize)) == NULL)
- {
- PDEBUG ("Cannot new plist Channel %sn", cname);
- free (data);
- return NULL;
- }
- pc->pcinfo->media = calloc (1, sizeof (struct MediaData));
- pc->pcinfo->media[0].start = 0;
- pc->pcinfo->media[0].len = pc->pcinfo->maxID;
- pc->pcinfo->media[0].dlen = dlen;
- pc->pcinfo->media[0].data = data;
- pc->pcinfo->cur_channel = pc->pcinfo->max_channel = 1;
- }
- return pc;
- }
- struct Channel *getProgrambymd5 (char *name, int len)
- {
- char buffer[MAX_DATA];
- struct Channel *result;
- if ((result = findProgram (name, len)) != NULL)
- return result;
- snprintf (buffer, MAX_DATA, "%s/%s/%s/", PREFIX, PROG_PREFIX, name);
- return add_prog (buffer, name);
- }
- int locateprog_by_id (struct Channel *pc, unsigned int id, char *buf, int max)
- {
- int i, pos, *msg;
- struct LiveChannelInfo *c = pc->pcinfo;
- if (c == NULL)
- {
- PDEBUG ("c is %p and id is (%d,%d).n", c, c->maxID, id);
- return -1;
- }
- i = id % c->maxID;
- pos = i / c->max_queue;
- i = i % c->max_queue;
- if (pc->maxblocksize + 2*sizeof(int) > max)
- {
- PDEBUG ("too small buffer %d for %d", max, pc->maxblocksize);
- return -2;
- }
- if (pos >= c->numinput || c->input[pos] == NULL)
- {
- PDEBUG ("file %d does not exist. (%d,%p)n", pos, c->numinput, c->input[pos]);
- return -1;
- }
- if (fseeko (c->input[pos], ((off_t)(i)) * pc->maxblocksize, SEEK_SET) != 0)
- {
- PDEBUG ("Fssek failed. (%d, %d, %d)n", pos, i, pc->maxblocksize);
- return -1;
- }
- if ((i=fread (buf+2*sizeof(int), 1, pc->maxblocksize, c->input[pos])) != pc->maxblocksize)
- {
- PDEBUG ("Fread failed. (%d, %d, %d)n", pos, i, pc->maxblocksize);
- return -1;
- }
- msg = (int *)buf;
- msg[0] = id;
- msg[1] = pc->maxblocksize;
- pc->upsize += msg[1];
- return msg[1];
- }
- inline void freeProgram (struct Channel *pc, void *p)
- {
- freeChannel (ProgramHash, &ProgramList, &NumNewProg, pc);
- }
- void freeAllProgram ()
- {
- apply_hash (ProgramHash, freeProgram, NULL);
- }