📄 parse_args.c
字号:
/* $Author: peltotas $ $Date: 2006/03/16 11:26:05 $ $Revision: 1.9 $ *//* * MAD-FLUTELIB: Implementation of FLUTE protocol. * Copyright (c) 2003-2006 TUT - Tampere University of Technology * main authors/contacts: jani.peltotalo@tut.fi and sami.peltotalo@tut.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 */#include "flute_inc.h"/* * This function validates and parses command line arguments * * Params: int argc: Number of command line arguments, * char **argv: Pointer to command line arguments, * arguments_t *a: Pointer to arguments structure where command line arguments are parsed. * * Return: int: 0 in success, -1 otherwise * */int validateargs(int argc, char **argv, arguments_t *a) { int i; unsigned int tmp_max_sb_len = 0; unsigned int tmp_es_len = 0; char *tmp_addr = NULL; unsigned char fec_enc = DEF_FEC; char *tmp_base_dir = NULL; #ifdef WIN32 ULONGLONG tmp_tsi; ULONGLONG duration = DEF_DURATION;#else char *ep; unsigned long long tmp_tsi; unsigned long long duration = DEF_DURATION;#endif int errno; div_t div_max_k; div_t div_max_n; char *loss_ratio2 = NULL; time_t systime; #ifdef WIN32 ULONGLONG curr_time;#else unsigned long long curr_time;#endif time(&systime); curr_time = systime + 2208988800U; /* Set default values for global parameters */ a->alc_a.cc_id = DEF_CC; /* congestion control */ a->alc_a.mode = RECEIVER; /* sender or receiver? */ tmp_tsi = DEF_TSI; /* transport session identifier */ a->toi = 0; /* transport object identifier */ a->alc_a.port = DEF_MCAST_PORT; /* local port number for base channel */ a->alc_a.nb_channel = DEF_NB_CHANNEL; /* number of channels */ a->alc_a.intface = NULL; /* interface */ a->alc_a.intface_name = NULL; /* interface name/index for IPv6 multicast join */ a->alc_a.addr_family = DEF_ADDR_FAMILY; a->alc_a.addr_type = 0; a->alc_a.es_len = DEF_SYMB_LENGTH; /* encoding symbol length */ a->alc_a.max_sb_len = DEF_MAX_SB_LEN; /* source block length */ a->alc_a.tx_rate = DEF_TX_RATE; /* transmission rate in kbit/s */ a->alc_a.ttl = DEF_TTL; /* time to live */ a->alc_a.nb_tx = DEF_TX_NB; /* nb of time to send the file/directory */ a->cont = false; /* continuous transmission */ a->alc_a.simul_losses = false; /* simulate packet losses */ a->alc_a.loss_ratio1 = P_LOSS_WHEN_OK; a->alc_a.loss_ratio2 = P_LOSS_WHEN_LOSS; a->alc_a.fec_ratio = DEF_FEC_RATIO; /* FEC ratio percent */ a->alc_a.fec_enc_id = DEF_FEC_ENC_ID; /* FEC Encoding */ a->alc_a.fec_inst_id = DEF_FEC_INST_ID; a->alc_a.rx_memory_mode = 1; a->alc_a.verbosity = -1; memset(a->file_path, 0, MAX_LENGTH); /* file(s) or directory to send */ memset(a->fdt_file, 0, MAX_LENGTH); strcpy(a->fdt_file, DEF_FDT); /* fdt file (fdt based send) */ a->rx_automatic = false; /* download files defined in IDT automatically */ a->rx_object = false; memset(a->sdp_file, 0, MAX_LENGTH); a->alc_a.use_fec_oti_ext_hdr = 0; /* include fec oti extension header to flute header */ a->alc_a.encode_content = 0; /* encode content */ #ifdef WIN32 a->open_file = false; /* open received file automatically */#endif #ifdef SSM a->alc_a.use_ssm = false; /* use source specific multicast */#endif a->alc_a.half_word = false; a->alc_a.accept_expired_fdt_inst = false; a->log_fd = -1; a->alc_a.mode = RECEIVER; a->complete_fdt = false; a->alc_a.src_addr = NULL; a->name_incomplete_objects = false; a->alc_a.optimize_tx_rate = false; a->alc_a.calculate_session_size = false; for(i = 1; i < argc ; i++) { if(argv[i][0] == '-') { switch(argv[i][1]) { case 'A': /* automatic download */ if(strlen(argv[i]) > 2) { return -1; } a->rx_automatic = true; break; case 'a': /* address family */ if(strlen(argv[i]) > 3) { if(!(strcmp(&argv[i][3], "IPv4"))) { a->alc_a.addr_family = PF_INET; } else if(!(strcmp(&argv[i][3], "IPv6"))) { a->alc_a.es_len = MAX_SYMB_LENGTH_IPv6_FEC_ID_0_130; a->alc_a.addr_family = PF_INET6; } } else { return -1; } break; case 'B': /* base directory for downloaded files */ if(strlen(argv[i]) > 3) { tmp_base_dir = &argv[i][3]; } else { return -1; } break; case 'b': /* rx_memory_mode */ if(strlen(argv[i]) > 3) { a->alc_a.rx_memory_mode = (unsigned char)atoi(&argv[i][3]); if(a->alc_a.rx_memory_mode > 2) { printf("Possible values for option -b are: 0, 1, or 2\n"); fflush(stdout); return -1; } } else { return -1; } break; case 'C': /* Continuous transmission */ if(strlen(argv[i]) > 2) { return -1; } a->cont = true; break; case 'c': /* number of channels */ if(strlen(argv[i]) > 3) { a->alc_a.nb_channel = (unsigned char)atoi(&argv[i][3]); if(a->alc_a.nb_channel > MAX_CHANNELS_IN_SESSION) { printf("Channel number set to maximum value: %i\n", MAX_CHANNELS_IN_SESSION); a->alc_a.nb_channel = MAX_CHANNELS_IN_SESSION; } else if(a->alc_a.nb_channel == 0) { printf("Channel number set to 1\n"); a->alc_a.nb_channel = 1; } } else { return -1; } break; case 'D': /* session duration time */ if(strlen(argv[i]) > 3) {#ifdef WIN32 duration = _atoi64(&argv[i][3]); if(duration > (ULONGLONG)0xFFFFFFFFFFFFFFFF) { printf("Duration: %I64u too big (max=%I64u)\n", duration, (ULONGLONG)0xFFFFFFFFFFFFFFFF); fflush(stdout); return -1; }#else duration = strtoull(&argv[i][3], &ep, 10); if(&argv[i][3] == '\0' || *ep != '\0') { printf("Duration not a number\n"); fflush(stdout); return -1; } if(errno == ERANGE && duration == 0xFFFFFFFFFFFFFFFFULL) { printf("Duration too big for unsigned long long (64 bits)\n"); fflush(stdout); return -1; }#endif } else { return -1; } break; case 'd': /* sdp file */ if(strlen(argv[i]) > 3) { memset(a->sdp_file, 0, MAX_LENGTH); strcpy(a->sdp_file, &argv[i][3]); } else { return -1; } break; case 'E': /* Accept Expired FDT Instances */ if(strlen(argv[i]) > 2) { return -1; } a->alc_a.accept_expired_fdt_inst = true; break; case 'e': /* Use fec oti extension header */ if(strlen(argv[i]) > 3) { a->alc_a.use_fec_oti_ext_hdr = (unsigned char)atoi(&argv[i][3]); if(a->alc_a.use_fec_oti_ext_hdr > 1) { printf("Possible values for option -e are: 0, or 1\n"); fflush(stdout); return -1; } } else { return -1; } break; case 'F': /* file(s) or directory to send/receive */ if(strlen(argv[i]) > 3) { memset(a->file_path, 0, MAX_LENGTH); strcpy(a->file_path, &argv[i][3]); } else { return -1; } memset(a->fdt_file, 0, MAX_LENGTH); break; case 'f': /* fdt based send */ if(strlen(argv[i]) > 3) { memset(a->fdt_file, 0, MAX_LENGTH); strcpy(a->fdt_file, &argv[i][3]); } else { return -1; } memset(a->file_path, 0, MAX_LENGTH); break; case 'G': /* Calculate session size but do not send anything */ if(strlen(argv[i]) > 2) { return -1; } a->alc_a.calculate_session_size = true; break; case 'H': /* use half-word */ if(strlen(argv[i]) > 2) { return -1; } a->alc_a.half_word = true; break; case 'h': /* help/usage */ return -1; break; case 'I': /* local interface name/index for IPv6 multicast join */ if(strlen(argv[i]) > 3) { a->alc_a.intface_name = &argv[i][3]; } else { return -1; } break; case 'i': /* local interface to use */ if(strlen(argv[i]) > 3) { a->alc_a.intface = &argv[i][3]; } else { return -1; } break; case 'K': /* Complete FDT */ if(strlen(argv[i]) > 2) { return -1; } a->complete_fdt = true; break; case 'L': /* sbl length */ if(strlen(argv[i]) > 3) { tmp_max_sb_len = (unsigned int)atoi(&argv[i][3]); } else { return -1; } break; case 'l': /* encoding symbol length */ if(strlen(argv[i]) > 3) { tmp_es_len = (unsigned short)atoi(&argv[i][3]); } else { return -1; } break;#ifdef SSM case 'M': /* use source specific multicast */ if(strlen(argv[i]) > 2) { return -1; } a->alc_a.use_ssm = true; break; case 'm': /* Multicast group for base channel */ if(strlen(argv[i]) > 3) { tmp_addr = &argv[i][3]; } else { return -1; } break;#endif case 'N': if(strlen(argv[i]) > 2) { return -1; } a->name_incomplete_objects = true; break; case 'n': /* tx loops */ if(strlen(argv[i]) > 3) { a->alc_a.nb_tx = (unsigned short)atoi(&argv[i][3]); } else { return -1; } break;#ifdef WIN32 case 'O': /* automatic opening */ if(strlen(argv[i]) > 2) { return -1; } a->open_file = true; break;#endif case 'o': /* toi */ if(strlen(argv[i]) > 3) {#ifdef WIN32 a->toi = _atoi64(&argv[i][3]); if(a->toi > (ULONGLONG)0xFFFFFFFFFFFFFFFF) { printf("TOI: %I64u too big (max=%I64u)\n", a->toi, (ULONGLONG)0xFFFFFFFFFFFFFFFF); fflush(stdout); return -1; }#else /*a->toi = atoll(&argv[i][3]);*/ a->toi = strtoull(&argv[i][3], &ep, 10); if(&argv[i][3] == '\0' || *ep != '\0') { printf("TOI not a number\n"); fflush(stdout); return -1; } if(errno == ERANGE && a->toi == 0xFFFFFFFFFFFFFFFFULL) { printf("TOI too big for unsigned long long (64 bits)\n"); fflush(stdout); return -1; }#endif a->rx_object = 1; } else { return -1; } break; case 'P': /* simulate packet losses */ if(strlen(argv[i]) >= 2) { a->alc_a.simul_losses = true; } if(strlen(argv[i]) > 3) { a->alc_a.loss_ratio1 = atof(strtok(&argv[i][3], ",")); loss_ratio2 = strtok(NULL, "\0"); if(loss_ratio2 == NULL) { return -1; } a->alc_a.loss_ratio2 = atof(loss_ratio2); } if(strlen(argv[i]) == 3) { return -1; } break; case 'p': /* Port number for base channel*/ if(strlen(argv[i]) > 3) { a->alc_a.port = &argv[i][3]; } else { return -1; } break; case 'r': /* Transmission rate in kbits/s */ if(strlen(argv[i]) > 3) { a->alc_a.tx_rate = (unsigned int)atoi(&argv[i][3]); } else { return -1; } break; case 'S': /* sender */ if(strlen(argv[i]) > 2) { return -1; } a->alc_a.mode = SENDER; a->toi = FDT_TOI; break; case 's': /* first alc session identifier */ if(strlen(argv[i]) > 3) { a->alc_a.src_addr = &argv[i][3]; } else { return -1; } break; case 'T': /* ttl */ if(strlen(argv[i]) > 3) { a->alc_a.ttl = (unsigned char)atoi(&argv[i][3]); } else { return -1; } break; case 't': /* second alc session identifier */ if(strlen(argv[i]) > 3) {#ifdef WIN32 tmp_tsi = _atoi64(&argv[i][3]);#else /*tmp_tsi = atoll(&argv[i][3]);*/ tmp_tsi = strtoull(&argv[i][3], &ep, 10); if(&argv[i][3] == '\0' || *ep != '\0') { printf("TSI not a number\n"); fflush(stdout); return -1; } if(errno == ERANGE && tmp_tsi == 0xFFFFFFFFFFFFFFFFULL) { printf("TSI too big for unsigned long long (64 bits)\n"); fflush(stdout); return -1; }#endif #ifdef WIN32 if(tmp_tsi > (ULONGLONG)0xFFFFFFFFFFFF) { printf("TSI: %I64u too big (max=%I64u)\n", tmp_tsi, (ULONGLONG)0xFFFFFFFFFFFF);#else if(tmp_tsi > 0xFFFFFFFFFFFFULL) { printf("TSI: %llu too big (max=%llu)\n", tmp_tsi, 0xFFFFFFFFFFFFULL);#endif fflush(stdout); return -1; } } else { return -1; } break; case 'U': /* unicast address */ if(strlen(argv[i]) > 2) { return -1; } a->alc_a.addr_type = 1; break; case 'V': /* redirect stderr and stdout into given file */ if (strlen(argv[i]) > 3) {#ifdef WIN32 a->log_fd = _open(&argv[i][3], _O_RDWR | _O_CREAT | _O_TRUNC, 0666);#else a->log_fd = open(&argv[i][3], O_RDWR | O_CREAT | O_TRUNC, 0666);#endif if(a->log_fd < 0) { printf("Log file: %s cannot be opened\n", &argv[i][3]); fflush(stdout); return -1; } #ifdef WIN32 _dup2(a->log_fd, _fileno(stdout)); _dup2(a->log_fd, _fileno(stderr));#else dup2(a->log_fd, fileno(stdout)); dup2(a->log_fd, fileno(stderr));#endif } break; case 'v': /* verbosity level */ if(strlen(argv[i]) > 3) { a->alc_a.verbosity = atoi(&argv[i][3]); if(a->alc_a.verbosity > 4) { printf("Possible values for option -v are: 0, 1, 2, 3, or 4\n"); fflush(stdout); return -1; } } else { return -1; } break; case 'w': /* congestion control */ if(strlen(argv[i]) > 3) { a->alc_a.cc_id = (unsigned char)atoi(&argv[i][3]); if(a->alc_a.cc_id > 1) { printf("Possible values for option -w are: 0, or 1\n"); fflush(stdout); return -1; } } else { return -1; } break; case 'X': /* FEC ratio percent */ if(strlen(argv[i]) > 3) { a->alc_a.fec_ratio = (unsigned short)atoi(&argv[i][3]); } else { return -1; } break; case 'x': /* fec encoding */ if(strlen(argv[i]) > 3) { fec_enc = (unsigned char)atoi(&argv[i][3]); if(fec_enc > 2) { printf("Possible values for option -x are: 0, 1, or 2\n"); fflush(stdout); return -1; } } else { return -1; } break; case 'Z': /* optimize transmission rate (use more CPU) */ if(strlen(argv[i]) > 2) { return -1; } a->alc_a.optimize_tx_rate = true; break; case 'z': /* encode content */ if(strlen(argv[i]) > 3) { a->alc_a.encode_content = (unsigned char)atoi(&argv[i][3]); if(a->alc_a.encode_content > 2) { printf("Possible values for option -z are: 0, 1, or 2\n"); fflush(stdout); return -1; } } else { return -1; } break; default: return -1; break; } } else { return -1; } } if(tmp_addr == NULL) { if(a->alc_a.addr_family == PF_INET) { tmp_addr = DEF_MCAST_IPv4_ADDR; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -