📄 network.c
字号:
/*********************************************************************** * network.c: network related utility functions *********************************************************************** * Copyright (C) 2007 metro <me_t_ro@yahoo.com> * * This file is part of msdl, media stream downloader * * network-unrelated functions goes to msdllib.c * * struct stream_t is a stream describer, and * stream_ctrl is stream controller, actually works as a * network buffer and wrapper for all supported protocols. * * * 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., * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. * ***********************************************************************/ #include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <ctype.h>#include <fcntl.h>#include <sys/time.h>#include <sys/types.h>#include <sys/select.h>#include <netdb.h>#include <netinet/in.h>#include <sys/socket.h>#include <arpa/inet.h>#include "msdl.h"#include "msdllib.h"#include "display.h"#include "network.h"/* * setup stream_t */struct stream_t *new_stream_t(void){ struct stream_t *st = (struct stream_t *)xmalloc(sizeof(struct stream_t)); return st;}/* * free stream_t */void free_stream_t(struct stream_t *st){ if(!st) return; free(st);}struct stream_t *streaming_init_common(){ struct stream_t *stream = new_stream_t(); stream->serverinfo = new_serverinfo_t(); stream->netsock = new_netsock_t(); stream->stream_ctrl = new_stream_ctrl_t(); stream->resumeinfo = new_resumeinfo_t(); return stream;}void streaming_close_common(struct stream_t *stream){ free(stream->localfile); free_resumeinfo_t(stream->resumeinfo); free_stream_ctrl_t(stream->stream_ctrl); free_netsock_t(stream->netsock); free_serverinfo_t(stream->serverinfo); free_stream_t(stream);}/* * setup buffer, setup URL. */struct stream_ctrl_t *new_stream_ctrl_t(void){ struct stream_ctrl_t *sc = (struct stream_ctrl_t *)xmalloc(sizeof(struct stream_ctrl_t)); sc->write_buffer = xmalloc(BUF_SIZE); sc->write_buffer_size = BUF_SIZE; return sc;}struct serverinfo_t *new_serverinfo_t(void){ struct serverinfo_t *si = (struct serverinfo_t *)xmalloc(sizeof(struct serverinfo_t)); return si;}void free_serverinfo_t(struct serverinfo_t *si){ if(!si) return; si->connect_host = NULL; if(si->host) free(si->host); if(si->proxy_host) free(si->proxy_host); free(si);}struct netsock_t *new_netsock_t(void){ struct netsock_t *ns = (struct netsock_t *)xmalloc(sizeof(struct netsock_t)); ns->buffer = xmalloc(BUF_SIZE); ns->buffer_size = BUF_SIZE; return ns;}void free_netsock_t(struct netsock_t *ns){ if(!ns) return; if(ns->buffer) free(ns->buffer); free(ns);}struct resumeinfo_t *new_resumeinfo_t(void){ struct resumeinfo_t *ri = (struct resumeinfo_t *)xmalloc(sizeof(struct resumeinfo_t)); ri->resume_req_success = 0; ri->resume_start_offset = 0; return ri;}void free_resumeinfo_t(struct resumeinfo_t *ri){ free(ri);}/* * free stream_ctrl; */void free_stream_ctrl_t(struct stream_ctrl_t *sc){ if(!sc) return; /* if(sc->url) free_url_t(sc->url); not malloc()ed in new_stream_ctrl_t, thus, free this outside free_stream_ctrl_t().*/ if(sc->write_buffer) free(sc->write_buffer); if(sc->retry_urlstr) free(sc->retry_urlstr); free(sc);}/* * set server information */void set_serverinfo(struct serverinfo_t *serverinfo, char *target_host,int target_port, char *proxy_host,int proxy_port,int protocol_default_port){ if(!serverinfo) { display(MSDL_ERR,"set_serverinfo: argument NULL\n"); return; } serverinfo->host = strdup(target_host); serverinfo->port = (target_port) ? target_port : protocol_default_port; serverinfo->connect_host = serverinfo->host; serverinfo->connect_port = serverinfo->port; if(proxy_host) { serverinfo->proxy_host = strdup(proxy_host); serverinfo->proxy_port = proxy_port; serverinfo->connect_host = serverinfo->proxy_host; /* reset host to connect() */ serverinfo->connect_port = serverinfo->proxy_port; /* reset port to connect() */ } else { serverinfo->proxy_host = NULL; serverinfo->proxy_port = 0; }}void set_serverinfo_by_proxy_string(struct serverinfo_t *serverinfo, char *host,int port,char *proxy_string, int protocol_default_port,int proxy_default_port){ char *proxy_str = NULL; int proxy_port = 0; if(proxy_string) { char *port_str = NULL; proxy_str = strdup(proxy_string); port_str = strchr(proxy_str,':'); if(!port_str) { display(MSDL_NOR,"proxy port not specified, assuming %d\n",proxy_default_port); proxy_port = proxy_default_port; } else { *port_str = '\0';/* separate proxy_str*/ port_str++; proxy_port = atoi(port_str); if(!proxy_port) { proxy_port = proxy_default_port; } } } set_serverinfo(serverinfo,host,port,proxy_str,proxy_port,protocol_default_port); if(proxy_str) free(proxy_str);}/* * return true if Speed string was valid * return value ... 1: valid 0: not valid * reason_ret ... "": no error some string: error reason */int speed_valid_and_guess(const char *str,int *guessed_speed,char **reason_ret){ /* 1*DIGIT [ "." *DIGIT ] */ int i = 0; int len = strlen(str); int speed_valid = 1; char *reason = NULL; int value = 0; value = 0; speed_valid = 1; for(i = 0 ; i < len ; i++) { if('0' <= str[i] && str[i] <= '9') { value *= 10; value += str[i] - '0'; continue; } else if(str[i] == '.') { if(i == 0) { reason = "\'.\' at the beginning of speed string"; speed_valid = 0; break; } i++; for(; i < len ; i++) { if(('0' <= str[i]) && (str[i] <= '9')) { continue; } else { reason = "invalid char after \'.\'"; speed_valid = 0; break; } } } else { reason = "invalid character"; speed_valid = 0; break; } } if(speed_valid) { reason = ""; if(reason_ret) { *reason_ret = reason; } /* do not care about guessed_speed */ return speed_valid; } /* invalid */ if(guessed_speed) { *guessed_speed = value; } if(reason_ret) { *reason_ret = reason; } return 0;}char *make_byterange_from_filesize(uint64_t filesize){ char *rangestr = (char *)xmalloc(256); snprintf(rangestr,255,"%llu-",(long long unsigned int)filesize); return rangestr;}/* * (url_t)->protocol_type. * sets UNKNONW_PROTOCOL if protocol string not supported. */int protocol_type_from_string(char *protocol){ int protocol_type = UNKNOWN_PROTOCOL; if(!strcasecmp(protocol,"mms") || !strcasecmp(protocol,"mmst")) { protocol_type = MMST; } else if(!strcasecmp(protocol,"mmsh")) { protocol_type = MMSH; } else if(!strcasecmp(protocol,"http")) { protocol_type = HTTP; } else if(!strcasecmp(protocol,"rtsp")) { protocol_type = RTSP; } else if(!strcasecmp(protocol,"ftp")) { protocol_type = FTP; } else { protocol_type = UNKNOWN_PROTOCOL; } return protocol_type;}/* * connect to 'servername' with 'port'. * return value : socket number ... success * -1 ... error */int server_connect(const char *servername,const int port){ int sock_server = 0; int ret; char hoststr[INET6_ADDRSTRLEN + 4]; /* IPv4 / IPv6 dual */ char portstr[8]; fd_set set; struct addrinfo hints,*result = NULL; struct timeval tv; int try_count = 0; if(!servername) { goto failed; } if(0 <= port && port <= 0xffff) { /* valid params */ snprintf(portstr,7,"%d",port); } else { display(MSDL_ERR,"port number %d not valid",port); goto failed; } memset(&hints,0,sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; ret = getaddrinfo(servername,portstr,&hints,&result); if(ret != 0) { display(MSDL_ERR,"Host [ %s ] not found. (%s)\n",servername,gai_strerror(ret)); goto failed; } if(result->ai_family == AF_INET6) { inet_ntop(result->ai_family, &((struct sockaddr_in6 *)result->ai_addr)->sin6_addr, hoststr, sizeof(hoststr));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -