⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 url_newsgroup.c

📁 MIDI解码程序(用VC编写)
💻 C
字号:
/*    TiMidity++ -- MIDI to WAVE converter and player    Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>    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*/#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#include <stdio.h>#include <stdlib.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif /* HAVE_UNISTD_H */#ifndef NO_STRING_H#include <string.h>#else#include <strings.h>#endif#include <signal.h> /* for SIGALRM */#include "timidity.h"#include "common.h"#include "url.h"#include "net.h"#define NNTP_OK_ID '2'#define MAX_LINE_BUFF 1024#define ALARM_TIMEOUT 10/* #define DEBUG */#ifdef URL_NEWS_XOVER_SUPPORTstatic char *xover_commands[] = {URL_NEWS_XOVER_SUPPORT, NULL};#elsestatic char *xover_commands[] = {NULL};#endif /* URL_NEWS_XOVER_SUPPORT */static VOLATILE int timeout_flag = 1;typedef struct _URL_newsgroup{    char common[sizeof(struct _URL)];    FILE *fp;    SOCKET fd;    int first, last;    int minID, maxID;    int xover;    int eof;    char *name;} URL_newsgroup;static int name_newsgroup_check(char *url_string);static long url_newsgroup_read(URL url, void *buff, long n);static char *url_newsgroup_gets(URL url, char *buff, int n);static void url_newsgroup_close(URL url);struct URL_module URL_module_newsgroup ={    URL_newsgroup_t,    name_newsgroup_check,    NULL,    url_newsgroup_open,    NULL};static int name_newsgroup_check(char *s){    if(strncmp(s, "news://", 7) == 0 && strchr(s, '@') == NULL)	return 1;    return 0;}/*ARGSUSED*/static void timeout(int sig){    timeout_flag = 1;}URL url_newsgroup_open(char *name){    URL_newsgroup *url;    SOCKET fd;    char *host, *p, *urlname;    unsigned short port;    char buff[BUFSIZ], group[256], *range;    int n;#ifdef DEBUG    printf("url_newsgroup_open(%s)\n", name);#endif /* DEBUG */    if((urlname = safe_strdup(name)) == NULL)	return NULL;    n = strlen(urlname);    while(n > 0 && urlname[n - 1] == '/')	urlname[--n] = '\0';    url = (URL_newsgroup *)alloc_url(sizeof(URL_newsgroup));    if(url == NULL)    {	url_errno = errno;	free(urlname);	errno = url_errno;	return NULL;    }    /* common members */    URLm(url, type)      = URL_newsgroup_t;    URLm(url, url_read)  = url_newsgroup_read;    URLm(url, url_gets)  = url_newsgroup_gets;    URLm(url, url_fgetc) = NULL;    URLm(url, url_seek)  = NULL;    URLm(url, url_tell)  = NULL;    URLm(url, url_close) = url_newsgroup_close;    /* private members */    url->fd = (SOCKET)-1;    url->fp = NULL;    url->xover = -1;    url->eof = 0;    url->first = url->last = 0;    url->minID = url->maxID = 0;    url->name = urlname;    if(strncmp(name, "news://", 7) == 0)	name += 7;    strncpy(buff, name, sizeof(buff) - 1);    buff[sizeof(buff) - 1] = '\0';    host = buff;    for(p = host; *p && *p != ':' && *p != '/'; p++)	;    if(*p == ':')    {	*p++ = '\0'; /* terminate `host' string */	port = atoi(p);	p = strchr(p, '/');	if(p == NULL)	{	    url_errno = URLERR_CANTOPEN;	    errno = ENOENT;	    url_newsgroup_close((URL)url);	    return NULL;	}    }    else	port = 119;    *p++ = '\0'; /* terminate `host' string */    strncpy(group, p, sizeof(group) - 1);    group[sizeof(group) - 1] = '\0';    if((range = strchr(group, '/')) != NULL)	*range++ = '\0';#ifdef DEBUG    printf("group: %s\n", group);#endif /* DEBUG */#ifdef DEBUG    printf("open(host=`%s', port=`%d')\n", host, port);#endif /* DEBUG */#ifdef __W32__    timeout_flag = 0;    fd = open_socket(host, port);#else    timeout_flag = 0;    signal(SIGALRM, timeout);    alarm(ALARM_TIMEOUT);    url->fd = fd = open_socket(host, port);    alarm(0);    signal(SIGALRM, SIG_DFL);#endif /* __W32__ */    if(fd == (SOCKET)-1)    {	VOLATILE_TOUCH(timeout_flag);#ifdef ETIMEDOUT	if(timeout_flag)	    errno = ETIMEDOUT;#endif /* ETIMEDOUT */	if(errno)	    url_errno = errno;	else	{	    url_errno = URLERR_CANTOPEN;	    errno = ENOENT;	}	url_newsgroup_close((URL)url);	return NULL;    }    if((url->fp = socket_fdopen(fd, "rb")) == NULL)    {	url_errno = errno;	closesocket(fd);	url_newsgroup_close((URL)url);	errno = url_errno;	return NULL;    }    if(socket_fgets(buff, sizeof(buff), url->fp) == NULL)    {	url_newsgroup_close((URL)url);	return NULL;    }#ifdef DEBUG    printf("Connect status: %s", buff);#endif /* DEBUG */    if(buff[0] != NNTP_OK_ID)    {	url_newsgroup_close((URL)url);	url_errno = URLERR_CANTOPEN;	errno = ENOENT;	return NULL;    }    sprintf(buff, "GROUP %s\r\n", group);#ifdef DEBUG    printf("CMD> %s", buff);#endif /* DEBUG */    socket_write(fd, buff, (long)strlen(buff));    if(socket_fgets(buff, sizeof(buff), url->fp) == NULL)    {	url_newsgroup_close((URL)url);	url_errno = URLERR_CANTOPEN;	errno = ENOENT;	return NULL;    }#ifdef DEBUG    printf("CMD< %s", buff);#endif /* DEBUG */    if(buff[0] != NNTP_OK_ID)    {	url_newsgroup_close((URL)url);	url_errno = URLERR_CANTOPEN;	errno = ENOENT;	return NULL;    }    p = buff + 4;    if(*p == '0') /* No article */	url->eof = 1;    p++;    while('0' <= *p && *p <= '9')	p++;    while(*p == ' ')	p++;    url->first = url->minID = atoi(p);    while('0' <= *p && *p <= '9')	p++;    while(*p == ' ')	p++;    url->last = url->maxID = atoi(p);    if(range != NULL)    {	if('0' <= *range && *range <= '9')	{	    url->first = atoi(range);	    if(url->first < url->minID)		url->first = url->minID;	}	if((range = strchr(range, '-')) != NULL)	{	    range++;	    if('0' <= *range && *range <= '9')	    {		url->last = atoi(range);		if(url->last > url->maxID)		    url->last = url->maxID;	    }	}    }    return (URL)url;}char *url_newsgroup_name(URL url){    if(url->type != URL_newsgroup_t)	return NULL;    return ((URL_newsgroup *)url)->name;}static void url_newsgroup_close(URL url){    URL_newsgroup *urlp = (URL_newsgroup *)url;    int save_errno = errno;    if(urlp->fd != (SOCKET)-1)    {	socket_write(urlp->fd, "QUIT\r\n", 6);	closesocket(urlp->fd);    }    if(urlp->fp != NULL)	socket_fclose(urlp->fp);    if(urlp->name != NULL)	free(urlp->name);    free(url);    errno = save_errno;}static long url_newsgroup_read(URL url, void *buff, long n){    char *p;    p = url_newsgroup_gets(url, (char *)buff, n);    if(p == NULL)	return 0;    return (long)strlen(p);}static char *url_newsgroup_gets(URL url, char *buff, int n){    URL_newsgroup *urlp = (URL_newsgroup *)url;    char linebuff[MAX_LINE_BUFF], *p, numbuf[32];    int i, j, nump;    int find_first;    if(urlp->eof || n <= 0)	return NULL;    if(n == 1)    {	buff[0] = '\0';	return buff;    }    find_first = 0;    if(urlp->xover == -1)    {	urlp->xover = 0;	for(i = 0; xover_commands[i] != NULL; i++)	{	    sprintf(linebuff, "%s %d-%d\r\n", xover_commands[i],		    urlp->first, urlp->last);#ifdef DEBUG	    printf("CMD> %s", linebuff);#endif /* DEBUG */	    socket_write(urlp->fd, linebuff, (long)strlen(linebuff));	    if(socket_fgets(linebuff, sizeof(linebuff), urlp->fp) == NULL)	    {		urlp->eof = 1;		return NULL;	    }#ifdef DEBUG	    printf("CMD< %s", linebuff);#endif /* DEBUG */	    if(linebuff[0] == NNTP_OK_ID)	    {		urlp->xover = 1;		break;	    }	}	if(!urlp->xover)	    find_first = 1;    }    else if(!urlp->xover)	socket_write(urlp->fd, "NEXT\r\n", 6);  next_read:    if(find_first)    {	for(i = urlp->first; i <= urlp->last; i++)	{	    sprintf(linebuff, "STAT %d\r\n", i);#ifdef DEBUG	    printf("CMD> %s", linebuff);#endif /* DEBUG */	    socket_write(urlp->fd, linebuff, (long)strlen(linebuff));	    if(socket_fgets(linebuff, sizeof(linebuff), urlp->fp) == NULL)	    {		urlp->eof = 1;		return NULL;	    }#ifdef DEBUG	    printf("CMD< %s", linebuff);#endif /* DEBUG */	    if(atoi(linebuff) != 423)		break;	}	if(i > urlp->last)	{	    urlp->eof = 1;	    return NULL;	}	find_first = 0;    }    else    {	if(socket_fgets(linebuff, sizeof(linebuff), urlp->fp) == NULL)	{	    urlp->eof = 1;	    return NULL;	}	i = strlen(linebuff);	if(i > 0 && linebuff[i - 1] != '\n')	{	    int c;	    do	    {		c = socket_fgetc(urlp->fp);	    } while(c != '\n' && c != EOF);	}    }    p = linebuff;#ifdef DEBUG    printf("line: %s", linebuff);#endif /* DEBUG */    if(urlp->xover == 0)    {	if(p[0] != '2')	{	    if(strncmp(p, "421", 3) == 0)	    {		urlp->eof = 1;		return NULL;	    }	    socket_write(urlp->fd, "NEXT\r\n", 6);	    goto next_read;	}	p += 3;	while(*p == ' ' || *p == '\t')	    p++;	nump = 0;	i = atoi(p);	if(i > urlp->last)	{	    urlp->eof = 1;	    return NULL;	}	if(i == urlp->last)	    urlp->eof = 1;	while('0' <= *p && *p <= '9' && nump < sizeof(numbuf))	    numbuf[nump++] = *p++;	if(nump == 0)	{	    socket_write(urlp->fd, "NEXT\r\n", 6);	    goto next_read;	}	if((p = strchr(linebuff, '<')) == NULL)	{	    socket_write(urlp->fd, "NEXT\r\n", 6);	    goto next_read;	}    }    else    {	int i;	if(linebuff[0] == '.')	{	    urlp->eof = 1;	    return NULL;	}	nump = 0;	while('0' <= linebuff[nump] && linebuff[nump] <= '9'	      && nump < sizeof(numbuf))	{	    numbuf[nump] = linebuff[nump];	    nump++;	}	for(i = 0; i < 4; i++)	{	    p = strchr(p, '\t');	    if(p == NULL)		goto next_read;	    p++;	}    }    if(*p == '<')	p++;    i = j = 0;    while(j < n - 2 && j < nump)    {	buff[j] = numbuf[j];	j++;    }    buff[j++] = ' ';    while(j < n - 1 && p[i] && p[i] != '>' && p[i] != ' ' && p[i] != '\t')    {	buff[j] = p[i];	i++;	j++;    }    buff[j] = '\0';    return buff;}#ifdef NEWSGROUP_MAINvoid *safe_malloc(int n) { return malloc(n); }void *safe_realloc(void *p, int n) { return realloc(p, n); }void main(int argc, char **argv){    URL url;    char buff[BUFSIZ];    if(argc != 2)    {	fprintf(stderr, "Usage: %s news-URL\n", argv[0]);	exit(1);    }    if((url = url_newsgroup_open(argv[1])) == NULL)    {	fprintf(stderr, "Can't open news group: %s\n", argv[1]);	exit(1);    }    while(url_gets(url, buff, sizeof(buff)) != NULL)	puts(buff);    url_close(url);    exit(0);}#endif /* NEWSGROUP_MAIN */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -