static void ParseArgs (int argc, char** argv) { int arg; char* opt; char parmBuf[256]; int len; /* bounds checking */ for (arg = 1; arg < argc; arg++) { opt = argv[arg]; if (*opt != '-') { warnx ("invalid option %s", opt); Usage (); } parmBuf[0] = '\0'; len = 0; while (arg < argc - 1) { if (argv[arg + 1][0] == '-') break; if (len) { strncat (parmBuf, " ", sizeof(parmBuf) - (len + 1)); len += strlen(parmBuf + len); } ++arg; strncat (parmBuf, argv[arg], sizeof(parmBuf) - (len + 1)); len += strlen(parmBuf + len); } ParseOption (opt + 1, (len ? parmBuf : NULL)); } }
int main(int argc, char* argv[]) { ParseOption(argc, argv); if(strPackFile=="") return 0; file.OpenFile(strPackFile.c_str()); if(bCompress) { file.CompactFile(); }else if(bUnpack) { }else while (optind < argc) { //non-option ARGV arguments = file list printf("Appending file = %s\n",argv[optind]); file.AppendSubFile(argv[optind],argv[optind]); optind++; } //file.DeleteSubFile("Makefile"); return 0; }
int main (int argc, char** argv) { int divertIn; int divertOut; int divertInOut; int routeSock; struct sockaddr_in addr; fd_set readMask; fd_set writeMask; int fdMax; /* * Initialize packet aliasing software. * Done already here to be able to alter option bits * during command line and configuration file processing. */ PacketAliasInit (); /* * Parse options. */ inPort = 0; outPort = 0; verbose = 0; inOutPort = 0; ifName = NULL; ifMTU = -1; background = 0; running = 1; assignAliasAddr = 0; aliasAddr.s_addr = INADDR_NONE; aliasOverhead = 12; dynamicMode = 0; logDropped = 0; logFacility = LOG_DAEMON; /* * Mark packet buffer empty. */ packetSock = -1; packetDirection = DONT_KNOW; ParseArgs (argc, argv); /* * Open syslog channel. */ openlog ("natd", LOG_CONS | LOG_PID | (verbose ? LOG_PERROR : 0), logFacility); /* * Check that valid aliasing address has been given. */ if (aliasAddr.s_addr == INADDR_NONE && ifName == NULL) errx (1, "aliasing address not given"); if (aliasAddr.s_addr != INADDR_NONE && ifName != NULL) errx (1, "both alias address and interface " "name are not allowed"); /* * Check that valid port number is known. */ if (inPort != 0 || outPort != 0) if (inPort == 0 || outPort == 0) errx (1, "both input and output ports are required"); if (inPort == 0 && outPort == 0 && inOutPort == 0) ParseOption ("port", DEFAULT_SERVICE); /* * Check if ignored packets should be dropped. */ dropIgnoredIncoming = PacketAliasSetMode (0, 0); dropIgnoredIncoming &= PKT_ALIAS_DENY_INCOMING; /* * Create divert sockets. Use only one socket if -p was specified * on command line. Otherwise, create separate sockets for * outgoing and incoming connnections. */ if (inOutPort) { divertInOut = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT); if (divertInOut == -1) Quit ("Unable to create divert socket."); divertIn = -1; divertOut = -1; /* * Bind socket. */ addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = inOutPort; if (bind (divertInOut, (struct sockaddr*) &addr, sizeof addr) == -1) Quit ("Unable to bind divert socket."); } else { divertIn = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT); if (divertIn == -1) Quit ("Unable to create incoming divert socket."); divertOut = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT); if (divertOut == -1) Quit ("Unable to create outgoing divert socket."); divertInOut = -1; /* * Bind divert sockets. */ addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = inPort; if (bind (divertIn, (struct sockaddr*) &addr, sizeof addr) == -1) Quit ("Unable to bind incoming divert socket."); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = outPort; if (bind (divertOut, (struct sockaddr*) &addr, sizeof addr) == -1) Quit ("Unable to bind outgoing divert socket."); } /* * Create routing socket if interface name specified and in dynamic mode. */ routeSock = -1; if (ifName) { if (dynamicMode) { routeSock = socket (PF_ROUTE, SOCK_RAW, 0); if (routeSock == -1) Quit ("Unable to create routing info socket."); assignAliasAddr = 1; } else SetAliasAddressFromIfName (ifName); } /* * Create socket for sending ICMP messages. */ icmpSock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); if (icmpSock == -1) Quit ("Unable to create ICMP socket."); /* * And disable reads for the socket, otherwise it slowly fills * up with received icmps which we do not use. */ shutdown(icmpSock, SHUT_RD); /* * Become a daemon unless verbose mode was requested. */ if (!verbose) DaemonMode (); /* * Catch signals to manage shutdown and * refresh of interface address. */ siginterrupt(SIGTERM, 1); siginterrupt(SIGHUP, 1); signal (SIGTERM, InitiateShutdown); signal (SIGHUP, RefreshAddr); /* * Set alias address if it has been given. */ if (aliasAddr.s_addr != INADDR_NONE) PacketAliasSetAddress (aliasAddr); /* * We need largest descriptor number for select. */ fdMax = -1; if (divertIn > fdMax) fdMax = divertIn; if (divertOut > fdMax) fdMax = divertOut; if (divertInOut > fdMax) fdMax = divertInOut; if (routeSock > fdMax) fdMax = routeSock; while (running) { if (divertInOut != -1 && !ifName && packetSock == -1) { /* * When using only one socket, just call * DoAliasing repeatedly to process packets. */ DoAliasing (divertInOut, DONT_KNOW); continue; } /* * Build read mask from socket descriptors to select. */ FD_ZERO (&readMask); FD_ZERO (&writeMask); /* * If there is unsent packet in buffer, use select * to check when socket comes writable again. */ if (packetSock != -1) { FD_SET (packetSock, &writeMask); } else { /* * No unsent packet exists - safe to check if * new ones are available. */ if (divertIn != -1) FD_SET (divertIn, &readMask); if (divertOut != -1) FD_SET (divertOut, &readMask); if (divertInOut != -1) FD_SET (divertInOut, &readMask); } /* * Routing info is processed always. */ if (routeSock != -1) FD_SET (routeSock, &readMask); if (select (fdMax + 1, &readMask, &writeMask, NULL, NULL) == -1) { if (errno == EINTR) continue; Quit ("Select failed."); } if (packetSock != -1) if (FD_ISSET (packetSock, &writeMask)) FlushPacketBuffer (packetSock); if (divertIn != -1) if (FD_ISSET (divertIn, &readMask)) DoAliasing (divertIn, INPUT); if (divertOut != -1) if (FD_ISSET (divertOut, &readMask)) DoAliasing (divertOut, OUTPUT); if (divertInOut != -1) if (FD_ISSET (divertInOut, &readMask)) DoAliasing (divertInOut, DONT_KNOW); if (routeSock != -1) if (FD_ISSET (routeSock, &readMask)) HandleRoutingInfo (routeSock); } if (background) unlink (PIDFILE); return 0; }
int ParseOptions(TCHAR *pszLine, OPTIONS *psO) { TCHAR *pszToken; TCHAR *pszValue; int iStart; int iLen; int iPrefix; iStart = iLen = 0; while (TRUE) { iStart = GetToken(iStart+iLen, pszLine, &iLen, &pszToken); if (-1 == iStart) return -1; iPrefix = ParseOption(pszToken, &pszValue); free(pszToken); switch(iPrefix) { case OPTION_ERROR: case OPTION_NO_VALUE: return -2; case OPTION_VERSION: if (!psO->bVersion || NULL != psO->pszVersion) { free(pszValue); return -3; } psO->pszVersion = pszValue; break; case OPTION_MODULE: if (!psO->bModule || NULL != psO->pszModule) { free(pszValue); return -4; } psO->pszModule = pszValue; break; case OPTION_ADDRESS: if (!psO->bAddress || NULL != psO->pszAddress) { free(pszValue); return -4; } psO->pszAddress = pszValue; break; case OPTION_MINIMUM_LENGTH: if (!psO->bMinimumLength || NULL != psO->pszMinimumLength) { free(pszValue); return -4; } psO->pszMinimumLength = pszValue; break; case OPTION_START_ADDRESS: if (!psO->bStartAddress || NULL != psO->pszStartAddress) { free(pszValue); return -4; } psO->pszStartAddress = pszValue; break; case OPTION_END_ADDRESS: if (!psO->bEndAddress || NULL != psO->pszEndAddress) { free(pszValue); return -4; } psO->pszEndAddress = pszValue; break; case OPTION_ALPHA_PERCENTAGE: if (!psO->bAlphaPercentage || NULL != psO->pszAlphaPercentage) { free(pszValue); return -4; } psO->pszAlphaPercentage = pszValue; break; case OPTION_REGEX: if (!psO->bRegex || NULL != psO->pszRegex) { free(pszValue); return -4; } psO->pszRegex = TrimDoubleQuotes(pszValue); free(pszValue); break; case OPTION_FILTER: if (!psO->bFilter || NULL != psO->pszFilter) { free(pszValue); return -4; } psO->pszFilter = pszValue; break; case OPTION_MEMORY: if (!psO->bMemory || NULL != psO->pszMemory) { free(pszValue); return -4; } psO->pszMemory = pszValue; break; case OPTION_EXECUTE: if (!psO->bExecute || NULL != psO->pszExecute) { free(pszValue); return -4; } psO->pszExecute = pszValue; break; case OPTION_UNKNOWN: case OPTION_NO_COLON: return iStart; default: free(pszValue); return -5; } } }
void ReadConfigFile (const char* fileName) { FILE* file; char buf[MAXPATHLEN]; char* ptr; char* option; int LineNum; LineNum = 0; file = fopen (fileName, "r"); if (!file) { snprintf (buf, sizeof(buf), "Cannot open config file %s.\n", fileName); fprintf(stderr, "%s", buf); exit (1); } while (fgets (buf, sizeof (buf), file)) { LineNum++; ptr = strchr (buf, '\n'); if (!ptr) { errx (1, "Config line #%d too long!", LineNum); } *ptr = '\0'; if (buf[0] == '#') { continue; } ptr = buf; /* * Skip white space at beginning of line. */ while (*ptr && isspace (*ptr)) ++ptr; if (*ptr == '\0') continue; /* * Extract option name. */ option = ptr; while (*ptr && !isspace (*ptr)) ++ptr; if (*ptr != '\0') { *ptr = '\0'; ++ptr; } /* * Skip white space between name and parms. */ while (*ptr && isspace (*ptr)) ++ptr; ParseOption (option, *ptr ? ptr : NULL, LineNum); } fclose (file); }
int main(int argc, char **argv) { int nStatus = RD_SUCCESS; // http streaming server char DEFAULT_HTTP_STREAMING_DEVICE[] = "0.0.0.0"; // 0.0.0.0 is any device char *httpStreamingDevice = DEFAULT_HTTP_STREAMING_DEVICE; // streaming device, default 0.0.0.0 int nHttpStreamingPort = 80; // port int opt; struct option longopts[] = { {"help", 0, NULL, 'h'}, {"host", 1, NULL, 'n'}, {"port", 1, NULL, 'c'}, {"socks", 1, NULL, 'S'}, {"protocol", 1, NULL, 'l'}, {"playpath", 1, NULL, 'y'}, {"rtmp", 1, NULL, 'r'}, {"swfUrl", 1, NULL, 's'}, {"tcUrl", 1, NULL, 't'}, {"pageUrl", 1, NULL, 'p'}, {"app", 1, NULL, 'a'}, #ifdef CRYPTO {"swfhash", 1, NULL, 'w'}, {"swfsize", 1, NULL, 'x'}, {"swfVfy", 1, NULL, 'W'}, {"swfAge", 1, NULL, 'X'}, #endif {"auth", 1, NULL, 'u'}, {"conn", 1, NULL, 'C'}, {"flashVer", 1, NULL, 'f'}, {"live", 0, NULL, 'v'}, //{"flv", 1, NULL, 'o'}, //{"resume", 0, NULL, 'e'}, {"timeout", 1, NULL, 'm'}, {"buffer", 1, NULL, 'b'}, //{"skip", 1, NULL, 'k'}, {"device", 1, NULL, 'D'}, {"sport", 1, NULL, 'g'}, {"subscribe", 1, NULL, 'd'}, {"start", 1, NULL, 'A'}, {"stop", 1, NULL, 'B'}, {"token", 1, NULL, 'T'}, {"debug", 0, NULL, 'z'}, {"quiet", 0, NULL, 'q'}, {"verbose", 0, NULL, 'V'}, {0, 0, 0, 0} }; RTMP_LogPrintf("HTTP-RTMP Stream Gateway %s\n", RTMPDUMP_VERSION); RTMP_LogPrintf("(c) 2010 Andrej Stepanchuk, Howard Chu; license: GPL\n\n"); // init request memset(&defaultRTMPRequest, 0, sizeof(RTMP_REQUEST)); defaultRTMPRequest.rtmpport = -1; defaultRTMPRequest.protocol = RTMP_PROTOCOL_UNDEFINED; defaultRTMPRequest.bLiveStream = FALSE; // is it a live stream? then we can't seek/resume defaultRTMPRequest.timeout = 120; // timeout connection after 120 seconds defaultRTMPRequest.bufferTime = 20 * 1000; defaultRTMPRequest.swfAge = 30; signal(SIGINT, sigIntHandler); #ifndef WIN32 signal(SIGPIPE, SIG_IGN); #endif InitSockets(); while ((opt = getopt_long(argc, argv, "hvqVzr:s:t:p:a:f:u:n:c:l:y:m:d:D:A:B:T:g:w:x:W:X:S:", longopts, NULL)) != -1) { switch (opt) { case 'h': RTMP_LogPrintf ("\nThis program serves media content streamed from RTMP onto HTTP.\n\n"); RTMP_LogPrintf("--help|-h Prints this help screen.\n"); RTMP_LogPrintf ("--rtmp|-r url URL (e.g. rtmp://host[:port]/path)\n"); RTMP_LogPrintf ("--host|-n hostname Overrides the hostname in the rtmp url\n"); RTMP_LogPrintf ("--port|-c port Overrides the port in the rtmp url\n"); RTMP_LogPrintf ("--socks|-S host:port Use the specified SOCKS proxy\n"); RTMP_LogPrintf ("--protocol|-l Overrides the protocol in the rtmp url (0 - RTMP, 2 - RTMPE)\n"); RTMP_LogPrintf ("--playpath|-y Overrides the playpath parsed from rtmp url\n"); RTMP_LogPrintf("--swfUrl|-s url URL to player swf file\n"); RTMP_LogPrintf ("--tcUrl|-t url URL to played stream (default: \"rtmp://host[:port]/app\")\n"); RTMP_LogPrintf("--pageUrl|-p url Web URL of played programme\n"); RTMP_LogPrintf("--app|-a app Name of target app in server\n"); #ifdef CRYPTO RTMP_LogPrintf ("--swfhash|-w hexstring SHA256 hash of the decompressed SWF file (32 bytes)\n"); RTMP_LogPrintf ("--swfsize|-x num Size of the decompressed SWF file, required for SWFVerification\n"); RTMP_LogPrintf ("--swfVfy|-W url URL to player swf file, compute hash/size automatically\n"); RTMP_LogPrintf ("--swfAge|-X days Number of days to use cached SWF hash before refreshing\n"); #endif RTMP_LogPrintf ("--auth|-u string Authentication string to be appended to the connect string\n"); RTMP_LogPrintf ("--conn|-C type:data Arbitrary AMF data to be appended to the connect string\n"); RTMP_LogPrintf (" B:boolean(0|1), S:string, N:number, O:object-flag(0|1),\n"); RTMP_LogPrintf (" Z:(null), NB:name:boolean, NS:name:string, NN:name:number\n"); RTMP_LogPrintf ("--flashVer|-f string Flash version string (default: \"%s\")\n", RTMP_DefaultFlashVer.av_val); RTMP_LogPrintf ("--live|-v Get a live stream, no --resume (seeking) of live streams possible\n"); RTMP_LogPrintf ("--subscribe|-d string Stream name to subscribe to (otherwise defaults to playpath if live is specified)\n"); RTMP_LogPrintf ("--timeout|-m num Timeout connection num seconds (default: %lu)\n", defaultRTMPRequest.timeout); RTMP_LogPrintf ("--start|-A num Start at num seconds into stream (not valid when using --live)\n"); RTMP_LogPrintf ("--stop|-B num Stop at num seconds into stream\n"); RTMP_LogPrintf ("--token|-T key Key for SecureToken response\n"); RTMP_LogPrintf ("--buffer|-b Buffer time in milliseconds (default: %lu)\n\n", defaultRTMPRequest.bufferTime); RTMP_LogPrintf ("--device|-D Streaming device ip address (default: %s)\n", DEFAULT_HTTP_STREAMING_DEVICE); RTMP_LogPrintf ("--sport|-g Streaming port (default: %d)\n\n", nHttpStreamingPort); RTMP_LogPrintf ("--quiet|-q Suppresses all command output.\n"); RTMP_LogPrintf("--verbose|-V Verbose command output.\n"); RTMP_LogPrintf("--debug|-z Debug level command output.\n"); RTMP_LogPrintf ("If you don't pass parameters for swfUrl, pageUrl, or auth these properties will not be included in the connect "); RTMP_LogPrintf("packet.\n\n"); return RD_SUCCESS; break; // streaming server specific options case 'D': if (inet_addr(optarg) == INADDR_NONE) { RTMP_Log(RTMP_LOGERROR, "Invalid binding address (requested address %s), ignoring", optarg); } else { httpStreamingDevice = optarg; } break; case 'g': { int port = atoi(optarg); if (port < 0 || port > 65535) { RTMP_Log(RTMP_LOGERROR, "Streaming port out of range (requested port %d), ignoring\n", port); } else { nHttpStreamingPort = port; } break; } default: //RTMP_LogPrintf("unknown option: %c\n", opt); if (!ParseOption(opt, optarg, &defaultRTMPRequest)) return RD_FAILED; break; } } #ifdef _DEBUG netstackdump = fopen("netstackdump", "wb"); netstackdump_read = fopen("netstackdump_read", "wb"); #endif // start text UI ThreadCreate(controlServerThread, 0); // start http streaming if ((httpServer = startStreaming(httpStreamingDevice, nHttpStreamingPort)) == 0) { RTMP_Log(RTMP_LOGERROR, "Failed to start HTTP server, exiting!"); return RD_FAILED; } RTMP_LogPrintf("Streaming on http://%s:%d\n", httpStreamingDevice, nHttpStreamingPort); while (httpServer->state != STREAMING_STOPPED) { sleep(1); } RTMP_Log(RTMP_LOGDEBUG, "Done, exiting..."); CleanupSockets(); #ifdef _DEBUG if (netstackdump != 0) fclose(netstackdump); if (netstackdump_read != 0) fclose(netstackdump_read); #endif return nStatus; }
void processTCPrequest(STREAMING_SERVER * server, // server socket and state (our listening socket) int sockfd // client connection socket ) { char buf[512] = { 0 }; // answer buffer char header[2048] = { 0 }; // request header char *filename = NULL; // GET request: file name //512 not enuf char *buffer = NULL; // stream buffer char *ptr = NULL; // header pointer int len; size_t nRead = 0; RTMP rtmp = { 0 }; uint32_t dSeek = 0; // can be used to start from a later point in the stream // reset RTMP options to defaults specified upon invokation of streams RTMP_REQUEST req; char srvhead[] = "\r\nServer: HTTP-RTMP Stream Server " RTMPDUMP_VERSION "\r\n"; // timeout for http requests fd_set fds; struct timeval tv; char *status = "404 Not Found"; server->state = STREAMING_IN_PROGRESS; memcpy(&req, &defaultRTMPRequest, sizeof(RTMP_REQUEST)); memset(&tv, 0, sizeof(struct timeval)); tv.tv_sec = 5; // go through request lines //do { FD_ZERO(&fds); FD_SET(sockfd, &fds); if (select(sockfd + 1, &fds, NULL, NULL, &tv) <= 0) { RTMP_Log(RTMP_LOGERROR, "Request timeout/select failed, ignoring request"); goto quit; } else { nRead = recv(sockfd, header, 2047, 0); header[2047] = '\0'; RTMP_Log(RTMP_LOGDEBUG, "%s: header: %s", __FUNCTION__, header); if (strstr(header, "Range: bytes=") != 0) { // TODO check range starts from 0 and asking till the end. RTMP_LogPrintf("%s, Range request not supported\n", __FUNCTION__); len = sprintf(buf, "HTTP/1.0 416 Requested Range Not Satisfiable%s\r\n", srvhead); send(sockfd, buf, len, 0); goto quit; } if (strncmp(header, "GET", 3) == 0 && nRead > 4) { char *p = filename; filename = header + 4; // filter " HTTP/..." from end of request while (*p != '\0') { if (*p == ' ') { *p = '\0'; break; } p++; } } } //} while(!isHTTPRequestEOF(header, nRead)); // if we got a filename from the GET method if (filename != NULL) { RTMP_Log(RTMP_LOGDEBUG, "%s: Request header: %s", __FUNCTION__, filename); if (filename[0] == '/') { // if its not empty, is it /? ptr = filename + 1; // parse parameters if (*ptr == '?') { int len; ptr++; len = strlen(ptr); while (len >= 2) { // get position of the next '&' char *temp; char ich = *ptr; unsigned int nArgLen; char *arg; ptr++; if (*ptr != '=') goto filenotfound; // long parameters not (yet) supported ptr++; len -= 2; nArgLen = len; if ((temp = strstr(ptr, "&")) != 0) { nArgLen = temp - ptr; } arg = (char *) malloc((nArgLen + 1) * sizeof(char)); memcpy(arg, ptr, nArgLen * sizeof(char)); arg[nArgLen] = '\0'; //RTMP_Log(RTMP_LOGDEBUG, "%s: unescaping parameter: %s", __FUNCTION__, arg); http_unescape(arg); RTMP_Log(RTMP_LOGDEBUG, "%s: parameter: %c, arg: %s", __FUNCTION__, ich, arg); ptr += nArgLen + 1; len -= nArgLen + 1; if (!ParseOption(ich, arg, &req)) { status = "400 unknown option"; goto filenotfound; } } } } else { goto filenotfound; } } else { RTMP_LogPrintf("%s: No request header received/unsupported method\n", __FUNCTION__); } // do necessary checks right here to make sure the combined request of default values and GET parameters is correct if (!req.hostname.av_len) { RTMP_Log(RTMP_LOGERROR, "You must specify a hostname (--host) or url (-r \"rtmp://host[:port]/playpath\") containing a hostname"); status = "400 Missing Hostname"; goto filenotfound; } if (req.playpath.av_len == 0) { RTMP_Log(RTMP_LOGERROR, "You must specify a playpath (--playpath) or url (-r \"rtmp://host[:port]/playpath\") containing a playpath"); status = "400 Missing Playpath"; goto filenotfound;; } if (req.protocol == RTMP_PROTOCOL_UNDEFINED) { RTMP_Log(RTMP_LOGWARNING, "You haven't specified a protocol (--protocol) or rtmp url (-r), using default protocol RTMP"); req.protocol = RTMP_PROTOCOL_RTMP; } if (req.rtmpport == -1) { RTMP_Log(RTMP_LOGWARNING, "You haven't specified a port (--port) or rtmp url (-r), using default port"); req.rtmpport = 0; } if (req.rtmpport == 0) { if (req.protocol & RTMP_FEATURE_SSL) req.rtmpport = 443; else if (req.protocol & RTMP_FEATURE_HTTP) req.rtmpport = 80; else req.rtmpport = 1935; } if (req.tcUrl.av_len == 0) { char str[512] = { 0 }; req.tcUrl.av_len = snprintf(str, 511, "%s://%.*s:%d/%.*s", RTMPProtocolStringsLower[req.protocol], req.hostname.av_len, req.hostname.av_val, req.rtmpport, req.app.av_len, req.app.av_val); req.tcUrl.av_val = (char *) malloc(req.tcUrl.av_len + 1); strcpy(req.tcUrl.av_val, str); } if (req.swfVfy) { #ifdef CRYPTO if (RTMP_HashSWF(req.swfUrl.av_val, &req.swfSize, req.hash, req.swfAge) == 0) { req.swfHash.av_val = (char *)req.hash; req.swfHash.av_len = RTMP_SWF_HASHLEN; } #endif } // after validation of the http request send response header len = sprintf(buf, "HTTP/1.0 200 OK%sContent-Type: video/flv\r\n\r\n", srvhead); send(sockfd, buf, len, 0); // send the packets buffer = (char *) calloc(PACKET_SIZE, 1); // User defined seek offset if (req.dStartOffset > 0) { if (req.bLiveStream) RTMP_Log(RTMP_LOGWARNING, "Can't seek in a live stream, ignoring --seek option"); else dSeek += req.dStartOffset; } if (dSeek != 0) { RTMP_LogPrintf("Starting at TS: %d ms\n", dSeek); } RTMP_Log(RTMP_LOGDEBUG, "Setting buffer time to: %dms", req.bufferTime); RTMP_Init(&rtmp); RTMP_SetBufferMS(&rtmp, req.bufferTime); RTMP_SetupStream(&rtmp, req.protocol, &req.hostname, req.rtmpport, &req.sockshost, &req.playpath, &req.tcUrl, &req.swfUrl, &req.pageUrl, &req.app, &req.auth, &req.swfHash, req.swfSize, &req.flashVer, &req.subscribepath, dSeek, req.dStopOffset, req.bLiveStream, req.timeout); /* backward compatibility, we always sent this as true before */ if (req.auth.av_len) rtmp.Link.lFlags |= RTMP_LF_AUTH; rtmp.Link.extras = req.extras; rtmp.Link.token = req.token; rtmp.m_read.timestamp = dSeek; RTMP_LogPrintf("Connecting ... port: %d, app: %s\n", req.rtmpport, req.app); if (!RTMP_Connect(&rtmp, NULL)) { RTMP_LogPrintf("%s, failed to connect!\n", __FUNCTION__); } else { unsigned long size = 0; double percent = 0; double duration = 0.0; int nWritten = 0; int nRead = 0; do { nRead = RTMP_Read(&rtmp, buffer, PACKET_SIZE); if (nRead > 0) { if ((nWritten = send(sockfd, buffer, nRead, 0)) < 0) { RTMP_Log(RTMP_LOGERROR, "%s, sending failed, error: %d", __FUNCTION__, GetSockError()); goto cleanup; // we are in STREAMING_IN_PROGRESS, so we'll go to STREAMING_ACCEPTING } size += nRead; //RTMP_LogPrintf("write %dbytes (%.1f KB)\n", nRead, nRead/1024.0); if (duration <= 0) // if duration unknown try to get it from the stream (onMetaData) duration = RTMP_GetDuration(&rtmp); if (duration > 0) { percent = ((double) (dSeek + rtmp.m_read.timestamp)) / (duration * 1000.0) * 100.0; percent = ((double) (int) (percent * 10.0)) / 10.0; RTMP_LogStatus("\r%.3f KB / %.2f sec (%.1f%%)", (double) size / 1024.0, (double) (rtmp.m_read.timestamp) / 1000.0, percent); } else { RTMP_LogStatus("\r%.3f KB / %.2f sec", (double) size / 1024.0, (double) (rtmp.m_read.timestamp) / 1000.0); } } #ifdef _DEBUG else { RTMP_Log(RTMP_LOGDEBUG, "zero read!"); } #endif } while (server->state == STREAMING_IN_PROGRESS && nRead > -1 && RTMP_IsConnected(&rtmp) && nWritten >= 0); } cleanup: RTMP_LogPrintf("Closing connection... "); RTMP_Close(&rtmp); RTMP_LogPrintf("done!\n\n"); quit: if (buffer) { free(buffer); buffer = NULL; } if (sockfd) closesocket(sockfd); if (server->state == STREAMING_IN_PROGRESS) server->state = STREAMING_ACCEPTING; return; filenotfound: RTMP_LogPrintf("%s, %s, %s\n", __FUNCTION__, status, filename); len = sprintf(buf, "HTTP/1.0 %s%s\r\n", status, srvhead); send(sockfd, buf, len, 0); goto quit; }
/* * File ::= { Declaration } * Declaration ::= Node * | Operation * | OperationCase * | Option * | Enum * | Literal * | Header * | Output * | Common * | Include * Literal ::= { LiteralFlag } ( LITERAL_DEFNS | LITERAL_END ) * LiteralFlag ::= %both | %decls | %end * Header ::= %header STRING * Output ::= %output STRING * Common ::= %common * Include ::= %include [ %readonly ] STRING */ void TreeCCParse(TreeCCContext *context) { /* Fetch the first token from the input stream */ if(!TreeCCNextToken(context->input)) { return; } /* Parse lines of input until the input is exhausted */ do { switch(context->input->token) { case TREECC_TOKEN_EOF: { /* Shouldn't happen, but ignore it if it does */ } break; case TREECC_TOKEN_IDENTIFIER: { /* Parse an operation case definition */ ParseOperationCase(context); } continue; /* Skip the call to TreeCCNextToken */ case TREECC_TOKEN_LITERAL_DEFNS: case TREECC_TOKEN_LITERAL_END: case TREECC_TOKEN_BOTH: case TREECC_TOKEN_DECLS: case TREECC_TOKEN_END: { /* Parse a literal definition block for this file */ int flags = 0; while(context->input->token == TREECC_TOKEN_BOTH || context->input->token == TREECC_TOKEN_DECLS || context->input->token == TREECC_TOKEN_END) { if(context->input->token == TREECC_TOKEN_BOTH) { flags |= TREECC_LITERAL_CODE | TREECC_LITERAL_DECLS; } else if(context->input->token == TREECC_TOKEN_DECLS) { flags |= TREECC_LITERAL_DECLS; } else { flags |= TREECC_LITERAL_END; } TreeCCNextToken(context->input); } if((flags & TREECC_LITERAL_DECLS) == 0) { flags |= TREECC_LITERAL_CODE; } if(context->input->token == TREECC_TOKEN_LITERAL_DEFNS) { TreeCCAddLiteralDefn(context, TreeCCValue(context->input), flags); } else if(context->input->token == TREECC_TOKEN_LITERAL_END) { TreeCCAddLiteralDefn(context, TreeCCValue(context->input), flags | TREECC_LITERAL_END); } else { TreeCCError(context->input, "literal definition block expected"); continue; } } break; case TREECC_TOKEN_NODE: { /* Parse a node definition */ ParseNode(context); } continue; /* Skip the call to TreeCCNextToken */ case TREECC_TOKEN_OPERATION: { /* Parse an operation definition */ ParseOperation(context); } continue; /* Skip the call to TreeCCNextToken */ case TREECC_TOKEN_OPTION: { /* Parse an option declaration */ ParseOption(context); } continue; /* Skip the call to TreeCCNextToken */ case TREECC_TOKEN_HEADER: { /* Parse a header filename specification */ TreeCCNextToken(context->input); if(context->input->token == TREECC_TOKEN_STRING) { TreeCCStream *stream = TreeCCStreamCreate(context, context->input->text, context->input->text, 1); context->headerStream = stream; stream->readOnly |= context->input->readOnly; if(!(context->commonHeader)) { context->commonHeader = stream; } } else { TreeCCError(context->input, "header filename expected"); continue; } } break; case TREECC_TOKEN_OUTPUT: { /* Parse an output filename specification */ TreeCCNextToken(context->input); if(context->input->token == TREECC_TOKEN_STRING) { TreeCCStream *stream = TreeCCStreamCreate(context, context->input->text, context->input->text, 0); context->sourceStream = stream; stream->readOnly |= context->input->readOnly; if(!(context->commonSource)) { context->commonSource = stream; } } else { TreeCCError(context->input, "output filename expected"); continue; } } break; case TREECC_TOKEN_OUTDIR: { /* Parse an output directory specification */ TreeCCNextToken(context->input); if(context->input->token == TREECC_TOKEN_STRING) { context->outputDirectory = TreeCCResolvePathname(context->input->filename, context->input->text); } else { TreeCCError(context->input, "output filename expected"); continue; } } break; case TREECC_TOKEN_ENUM: { /* Parse an enumerated type definition */ ParseEnum(context); } continue; /* Skip the call to TreeCCNextToken */ case TREECC_TOKEN_COMMON: { /* Put the common housekeeping code in the current header and source streams */ context->commonHeader = context->headerStream; context->commonSource = context->sourceStream; } break; case TREECC_TOKEN_INCLUDE: { /* Include another file at this point */ int readOnly = context->input->readOnly; TreeCCNextToken(context->input); if(context->input->token == TREECC_TOKEN_READONLY) { readOnly = 1; TreeCCNextToken(context->input); } if(context->input->token == TREECC_TOKEN_STRING) { char *includeFile = TreeCCResolvePathname(context->input->filename, context->input->text); FILE *file = fopen(includeFile, "r"); if(file != NULL) { /* Parse the contents of the included file */ TreeCCInput *newInput = (TreeCCInput *)malloc(sizeof(TreeCCInput)); TreeCCInput *origInput = context->input; if(!newInput) { TreeCCOutOfMemory(context->input); } TreeCCOpen(newInput, context->input->progname, file, includeFile); context->input = newInput; TreeCCParse(context); context->input = origInput; TreeCCClose(newInput, 1); free(newInput); } else { TreeCCError(context->input, "cannot open \"%s\"", includeFile); free(includeFile); } } else { TreeCCError(context->input, "include filename expected"); } } break; case TREECC_TOKEN_LITERAL_CODE: case TREECC_TOKEN_LPAREN: case TREECC_TOKEN_RPAREN: case TREECC_TOKEN_LBRACE: case TREECC_TOKEN_RBRACE: case TREECC_TOKEN_LSQUARE: case TREECC_TOKEN_RSQUARE: case TREECC_TOKEN_COMMA: case TREECC_TOKEN_EQUALS: case TREECC_TOKEN_STAR: case TREECC_TOKEN_REF: case TREECC_TOKEN_SEMI: case TREECC_TOKEN_COLON_COLON: case TREECC_TOKEN_STRING: case TREECC_TOKEN_UNKNOWN: case TREECC_TOKEN_ABSTRACT: case TREECC_TOKEN_TYPEDEF: case TREECC_TOKEN_NOCREATE: case TREECC_TOKEN_VIRTUAL: case TREECC_TOKEN_INLINE: case TREECC_TOKEN_SPLIT: case TREECC_TOKEN_READONLY: { /* This token is not valid here */ TreeCCError(context->input, "declaration expected"); do { /* Attempt to re-synchronise on the next declaration */ TreeCCNextToken(context->input); } while(!IsStartDecl(context->input->token)); } continue; /* Skip the call to TreeCCNextToken */ } /* Get the next token from the input stream */ TreeCCNextToken(context->input); } while(context->input->token != TREECC_TOKEN_EOF); }
Common::Error GagEngine::ScriptEvent(const Common::String &value) { Common::StringTokenizer tokenizer(value, Common::String(_OPTION_PREFIX)); Event event; event.name = tokenizer.nextToken(); event.name.trim(); if(event.name.empty()) return Common::Error(Common::kUnknownError, "[Script Event] unnamed event"); if(tokenizer.empty()) return Common::Error(Common::kUnknownError, "[Script Event] no options"); do { Common::String option_line(tokenizer.nextToken()); option_line.trim(); Option option; ParseOption(option, option_line); if(option.name == "C") { ; } else if(option.name == "COMM") { ; } else if(option.name == "DEST") { ; } else if(option.name == "IMAGE") { ; } else if(option.name == "KEYUP") { ; } else if(option.name == "R") { ; } else if(option.name == "RECT") { ; } else if(option.name == "SOUR") { ; } else if(option.name == "TRANSPARENT") { ; } else if(option.name == "ZONE") { ; } // command for on event execution else { if(option.name[0] != '*') { event.commands.push_back(option); //DEBUG #ifdef DEBUG_SKIM_SCRIPT G_STRING_SET.insert(option.name); #endif } } } while(!tokenizer.empty()); _events.push_back(event); return Common::Error(Common::kNoError); }
uint32_t TDNFCliParseArgs( int argc, char* const* argv, PTDNF_CMD_ARGS* ppCmdArgs ) { uint32_t dwError = 0; PTDNF_CMD_ARGS pCmdArgs = NULL; int nOptionIndex = 0; int nOption = 0; int nIndex = 0; char* pszDefaultInstallRoot = "/"; if(!ppCmdArgs) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_CLI_ERROR(dwError); } dwError = TDNFAllocateMemory( 1, sizeof(TDNF_CMD_ARGS), (void**)&pCmdArgs); BAIL_ON_CLI_ERROR(dwError); opterr = 0;//tell getopt to not print errors while (1) { nOption = getopt_long ( argc, argv, "46bCc:d:e:hiqvxy", pstOptions, &nOptionIndex); if (nOption == -1) break; switch (nOption) { case 0: dwError = ParseOption( pstOptions[nOptionIndex].name, optarg, pCmdArgs); BAIL_ON_CLI_ERROR(dwError); break; case 'b': _opt.nBest = 1; break; case 'e': break; case 'C': _opt.nCacheOnly = 1; break; case 'h': _opt.nShowHelp = 1; break; case 'i': dwError = TDNFAllocateString( optarg, &pCmdArgs->pszInstallRoot); BAIL_ON_CLI_ERROR(dwError); break; case 'r': break; case 'y': _opt.nAssumeYes = 1; break; case '4': _opt.nIPv4 = 1; break; case '6': _opt.nIPv6 = 1; break; case 'v': _opt.nVerbose = 1; break; case '?': dwError = HandleOptionsError(argv[optind-1], optarg, pstOptions); BAIL_ON_CLI_ERROR(dwError); //TODO: Handle unknown option, incomplete options break; } } if(pCmdArgs->pszInstallRoot == NULL) { dwError = TDNFAllocateString( pszDefaultInstallRoot, &pCmdArgs->pszInstallRoot); BAIL_ON_CLI_ERROR(dwError); } dwError = TDNFCopyOptions(&_opt, pCmdArgs); BAIL_ON_CLI_ERROR(dwError); //Collect extra args if (optind < argc) { pCmdArgs->nCmdCount = argc-optind; dwError = TDNFAllocateMemory( pCmdArgs->nCmdCount, sizeof(char*), (void**)&pCmdArgs->ppszCmds); BAIL_ON_CLI_ERROR(dwError); while (optind < argc) { dwError = TDNFAllocateString( argv[optind++], &pCmdArgs->ppszCmds[nIndex++]); BAIL_ON_CLI_ERROR(dwError); } } *ppCmdArgs = pCmdArgs; cleanup: return dwError; error: if(ppCmdArgs) { *ppCmdArgs = NULL; } if(pCmdArgs) { TDNFFreeCmdArgs(pCmdArgs); } goto cleanup; }
/** Function to parse the command line options. Responsible to 1. Parse the input values. 2. Print the usage note. 3. Identify the valdations to be carried out. 4. Type of report needs to be generated. @internalComponent @released @param aArgc - argument count @param aArgv[] - argument values */ ReturnType CmdLineHandler::ProcessCommandLine(unsigned int aArgc, char* aArgv[]) { if(aArgc < 2) { std::cout << PrintVersion().c_str() << std::endl; std::cout << PrintUsage().c_str() << std::endl; return EQuit; } ArgumentList argumentList(&aArgv[0], aArgv + aArgc); int argCount = argumentList.size(); iInputCommand = KToolName; for( int i = 1; i < argCount; i++ ) //Skip tool name { String name = argumentList.at(i); iInputCommand += " "; iInputCommand += name; int longOptionFlag = 0; if(IsOption(name, longOptionFlag)) { String optionName; bool optionValue = false; StringList optionValueList; ParseOption(name, optionName, optionValueList, optionValue); char shortOption = KNull; if(Validate(ReaderUtil::ToLower(optionName), optionValue, optionValueList.size())) { if(longOptionFlag) { shortOption = optionName.at(2); } else { shortOption = optionName.at(1); } } switch(shortOption) { case 'q': iCommmandFlag |= QuietMode; break; case 'a': iCommmandFlag |= KAll; break; case 'x': iCommmandFlag |= KXmlReport; break; case 'o': iXmlFileName.assign(optionValueList.front()); NormaliseName(); break; case 's': if((optionName == KShortSuppressOption) || (optionName == KLongSuppressOption)) { String value; while(optionValueList.size() > 0) { value = optionValueList.front(); if(iSuppressVal[value]) { if(iValidations > 0) //Is any check enabled? { if(iValidations & iSuppressVal[value]) { iValidations ^= iSuppressVal[value]; //Consider only 3 LSB's } } else //Is this valid value? { iSuppressions |= iSuppressVal[value]; } } else { throw ExceptionReporter(UNKNOWNSUPPRESSVAL,(char*)(optionValueList.front().c_str())); } optionValueList.pop_front(); } } else if(optionName == KLongEnableSidCheck) { iValidations |= KMarkEnable; iValidations |= ESid; } else if(optionName == KLongSidAllOption) { iCommmandFlag |= KSidAll; } break; case 'd': if(optionName == KLongEnableDbgFlagCheck) { iValidations |= KMarkEnable; iValidations |= EDbg; if(optionValueList.size() > 0) { if(optionValueList.front() == String("true")) { iDebuggableFlagVal = true; } else if (optionValueList.front() == String("false")) { iDebuggableFlagVal = false; } else { throw ExceptionReporter(UNKNOWNDBGVALUE); } } } else if (optionName == KLongEnableDepCheck) { iValidations |= KMarkEnable; iValidations |= EDep; } break; case 'e': if (optionName == KLongE32InputOption) { iCommmandFlag |= KE32Input; } break; case 'v': if(optionName == KLongVidValOption) { StringListToUnIntList(optionValueList, iVidValList); } else if(optionName == KLongEnableVidCheck) { iValidations |= KMarkEnable; iValidations |= EVid; } else { iCommmandFlag |= KVerbose; /**Initialize ExceptionImplementation class with verbose mode flag to print all status information to standard output*/ ExceptionImplementation::Instance(iCommmandFlag); } break; case 'n': iCommmandFlag |= KNoCheck; break; case 'h': std::cout << PrintVersion().c_str() << std::endl; std::cout << PrintUsage().c_str() << std::endl; return EQuit; //Don't proceed further } } else { if(!AlreadyReceived(name)) { iImageNameList.push_back(name); } else { ExceptionReporter(IMAGENAMEALREADYRECEIVED, (char*)name.c_str()).Report(); } iNoImage = false; } } //While loop ends here if((iCommmandFlag || iValidations || iSuppressions) && iNoImage) { PrintVersion(); PrintUsage(); } //Always log the version information into log file ExceptionImplementation::Instance(iCommmandFlag)->Log(iVersion); ValidateArguments(); ValidateE32NoCheckArguments(); if(iCommmandFlag & KE32Input) { ValidateImageNameList(); } return ESuccess; }
int InvokeProgram(int oftype) { List p = NULL; char **cmd; char *file; int status = 0; switch (oftype) { case PP_FILE: if (Option.cfiles == NULL) return 0; for (p = Option.cfiles; p != NULL; p = p->next) { PPFiles = ListAppend(PPFiles, FileName(p->str, ".i")); } Option.pfiles = ListCombine(Option.pfiles, PPFiles); cmd = BuildCommand(CPPProg, Option.pflags, Option.cfiles, PPFiles); status = _spawnvp(_P_WAIT, cmd[0], cmd); for (p = PPFiles; p != NULL; p = p->next) { if ((file = strrchr(p->str, '\\')) || (file = strrchr(p->str, '/'))) { rename(file + 1, p->str); } } break; case ASM_FILE: if (Option.pfiles == NULL) return 0; for (p = Option.pfiles; p != NULL; p = p->next) { ASMFiles = ListAppend(ASMFiles, FileName(p->str, ".asm")); } Option.afiles = ListCombine(Option.afiles, ASMFiles); cmd = BuildCommand(CCProg, Option.cflags, Option.pfiles, ASMFiles); status = _spawnvp(_P_WAIT, cmd[0], cmd); break; case OBJ_FILE: if (Option.afiles == NULL) return 0; for (p = Option.aflags, Option.aflags = NULL; p != NULL; p = p->next) { Option.aflags = ListCombine(Option.aflags, ParseOption(p->str + 4)); } for (p = Option.afiles; p != NULL; p = p->next) { file = FileName(p->str, ".obj"); OBJFiles = ListAppend(OBJFiles, file); cmd = BuildCommand(ASProg, Option.aflags, ListAppend(NULL, p->str), ListAppend(NULL, file)); status = _spawnvp(_P_WAIT, cmd[0], cmd); } Option.ofiles = ListCombine(Option.ofiles, OBJFiles); break; case LIB_FILE: break; case EXE_FILE: if (Option.ofiles == NULL) return 0; if (Option.out == NULL) { Option.out = Option.ofiles->str; } Option.out = FileName(Option.out, ".exe"); for (p = Option.lflags, Option.lflags = NULL; p != NULL; p = p->next) { Option.lflags = ListCombine(Option.lflags, ParseOption(p->str + 4)); } cmd = BuildCommand(LDProg, Option.lflags, Option.linput, ListAppend(NULL, Option.out)); status = _spawnvp(_P_WAIT, cmd[0], cmd); break; } return status; }
sc_status scParseCommandLineOptions( sc_session session, sc_uint argc, const char **argv, sc_uint expected, sc_option* options) { int i, o; cl_bool *found = scAllocate(session, sizeof(sc_bool) * expected); if(!found) return SC_OUT_OF_HOST_MEMORY; memset(found, SC_FALSE, sizeof(sc_bool) * expected); for (i = 0; i < argc && argv && argv[i]; i++) { for(o = 0; o < expected; o++) { if(found[o] == SC_TRUE) continue; const char* start = argv[i]; if(start[0] != '-') continue; const char* name = scGetOptionName(options[o], NULL); scDebug(session, "ceParseCommandLineOptions: Parsing '%s'\n", name); const char* str = strstr(argv[i], name); if(str && str - start <= 2) { const char* assign = strstr(str, "="); if(assign) { scDebug(session, "ceParseCommandLineOptions: Parsed '%s' as '%s'\n", name, &assign[1]); ParseOption(&assign[1], options[o]); sc_value value = scGetOptionValue(options[o], NULL); scDebug(session, "ceParseCommandLineOptions: Parsed '%s' as '%s' -> '%s' (%s)\n", name, argv[i], scGetSymbolName(scCreateSymbolFromValue(session, value, NULL) ), scGetTypeString(scGetValueType(value, NULL), NULL)); found[o] = SC_TRUE; } else if(i + 1 < argc && argv[i + 1]) { scDebug(session, "ceParseCommandLineOptions: Parsed '%s' as '%s'\n", name, argv[i]); ParseOption(argv[i], options[o]); sc_value value = scGetOptionValue(options[o], NULL); scDebug(session, "ceParseCommandLineOptions: Parsed '%s' as '%s' -> '%s' (%s)\n", name, argv[i], scGetSymbolName(scCreateSymbolFromValue(session, value, NULL) ), scGetTypeString(scGetValueType(value, NULL), NULL)); found[o] = SC_TRUE; } if(found[o] == SC_TRUE) break; } } if(found[o] == SC_TRUE) continue; } scDeallocate(session, found); return SC_SUCCESS; }