Exemplo n.º 1
0
/* Parse all CLI arguments */
int options_parse(struct options_t **opt, int argc, char **argv, int error_check) {
	int c = 0;
	char *ctmp = NULL;
	int itmp;
#ifndef __FreeBSD__	
	char *mask;
	regex_t regex;
	int reti;
#endif
	
	/* Reservate enough memory to store all variables */
	longarg = malloc(sizeof(char)*255);
	shortarg = malloc(sizeof(char)*3);
	optarg = malloc(sizeof(char)*255);

	/* Clear the argument holders */
	memset(longarg, '\0', sizeof(char)*255);
	memset(shortarg, '\0', sizeof(char)*3);
	memset(optarg, '\0', sizeof(char)*255);

	/* If have readed all arguments, exit and reset */
	if(getOptPos>=(argc-1)) {
		getOptPos=0;
		return -1;
	} else {
		getOptPos++;

		/* Check if the CLI character contains an equals to (=) sign.
		   If it does, we have probably encountered a long argument */
		if(strchr(argv[getOptPos],'=') != NULL) {
			/* Copy all characters until the equals to sign.
			   This will probably be the name of the argument */
			memcpy(longarg, &argv[getOptPos][0], strcspn(argv[getOptPos],"="));
			longarg[strcspn(argv[getOptPos],"=")]='\0';

			/* Then copy everything after the equals sign.
			   This will probably be the value of the argument */
			memcpy(optarg, &argv[getOptPos][strcspn(argv[getOptPos],"=")+1], strlen(argv[getOptPos]));
			optarg[strlen(argv[getOptPos])-(strcspn(argv[getOptPos],"=")+1)]='\0';
		} else {
			/* If the argument does not contain a equals sign.
			   Store the argument to check later if it's a long argument */
			longarg=strdup(argv[getOptPos]);
		}

		/* A short argument only contains of two characters.
		   So only store the first two characters */
		memcpy(shortarg, &argv[getOptPos][0], 2);

		/* Check if the short argument and the long argument are equal,
		   then we probably encountered a short argument. Only store the
		   identifier character. If there are more CLI characters
		   after the current one, store it as the CLI value. However, only
		   do this if the first character of the argument doesn't contain*/
		if(strcmp(longarg,shortarg) == 0 && (getOptPos+1)<argc && argv[getOptPos+1][0] != '-') {
			optarg=strdup(argv[getOptPos+1]);
			c=shortarg[1];
			getOptPos++;
		} else {
			/* If the short argument and the long argument are not equal,
			    then we probably encountered a long argument. */
			ctmp = malloc(strlen(longarg));
			if(longarg[0] == '-' && longarg[1] == '-') {
				memcpy(ctmp, &longarg[2], strlen(longarg));
				ctmp[strlen(longarg)] = '\0';

				/* Retrieve the short identifier for the logn argument */
				if(options_get_id(opt, ctmp, &itmp) == 0) {
					c=itmp;
				} else if(argv[getOptPos][0] == '-') {
					c=shortarg[1];
				}
			} else if(argv[getOptPos][0] == '-' && strstr(shortarg, longarg) != 0) {
				c=shortarg[1];
			}
		}

		/* Check if the argument was expected */
		if(options_get_name(opt, c, &ctmp) != 0 && c > 0) {
			if(error_check == 1) {
				if(strcmp(longarg,shortarg) == 0) {
					if(shortarg[0] == '-') {
						logprintf(LOG_ERR, "invalid option -- '-%c'", c);
					} else {
						logprintf(LOG_ERR, "invalid option -- '%s'", longarg);
					}
				} else {
					logprintf(LOG_ERR, "invalid option -- '%s'", longarg);
				}
				exit(EXIT_FAILURE);
			} else {
				return 0;
			}
		/* Check if an argument cannot have an argument that was set */
		} else if(strlen(optarg) != 0 && options_get_argtype(opt, c, &itmp) == 0 && itmp == 1) {
			if(error_check == 1) {
				if(strcmp(longarg,shortarg) == 0) {
					logprintf(LOG_ERR, "option '-%c' doesn't take an argument", c);
				} else {
					logprintf(LOG_ERR, "option '%s' doesn't take an argument", longarg);
				}
				exit(EXIT_FAILURE);
			} else {
				return 0;
			}
		/* Check if an argument required a value that wasn't set */
		} else if(strlen(optarg) == 0 && options_get_argtype(opt, c, &itmp) == 0 && itmp == 2) {
			if(error_check == 1) {
				if(strcmp(longarg, shortarg) == 0) {
					logprintf(LOG_ERR, "option '-%c' requires an argument", c);
				} else {
					logprintf(LOG_ERR, "option '%s' requires an argument", longarg);
				}
				exit(EXIT_FAILURE);
			} else {
				return 0;
			}
		/* Check if we have a valid argument */
		} else if(c == 0) {
			if(error_check == 1) {
				if(shortarg[0] == '-' && strstr(shortarg, longarg) != 0) {
					logprintf(LOG_ERR, "invalid option -- '-%c'", c);
				} else {
					logprintf(LOG_ERR, "invalid option -- '%s'", longarg);
				}
				exit(EXIT_FAILURE);
			} else {
				return 0;
			}
		} else {
			/* If the argument didn't have a value, set it to 1 */
			if(strlen(optarg) == 0)
				options_set_value(opt, c, "1");
			else {
#ifndef __FreeBSD__			
				/* If the argument has a regex mask, check if it passes */
				if(options_get_mask(opt, c, &mask) == 0) {
					reti = regcomp(&regex, mask, REG_EXTENDED);
					if(reti) {
						logprintf(LOG_ERR, "could not compile regex");
						exit(EXIT_FAILURE);
					}
					reti = regexec(&regex, optarg, 0, NULL, 0);
					if(reti == REG_NOMATCH || reti != 0) {
						if(shortarg[0] == '-') {
							logprintf(LOG_ERR, "invalid format -- '-%c'", c);
						} else {
							logprintf(LOG_ERR, "invalid format -- '%s'", longarg);
						}
						logprintf(LOG_ERR, "requires %s", mask);
						exit(EXIT_FAILURE);
					}
				}
#endif
				options_set_value(opt, c, optarg);
			}
			return c;
		}
	}
}
Exemplo n.º 2
0
/* Parse all CLI arguments */
int options_parse(struct options_t **opt, int argc, char **argv, int error_check, char **optarg) {
	logprintf(LOG_STACK, "%s(...)", __FUNCTION__);

	int c = 0;
	int itmp = 0;
#ifndef __FreeBSD__
	char *mask;
	regex_t regex;
	int reti;
#endif

	char *ctmp = NULL;

	/* If have read all arguments, exit and reset */
	if(getOptPos>=(argc-1)) {
		getOptPos=0;
		if(*optarg) {
			FREE(*optarg);
			*optarg = NULL;
		}
		return -1;
	} else {
		getOptPos++;
		/* Reserve enough memory to store all variables */
		longarg = REALLOC(longarg, 4);
		shortarg = REALLOC(shortarg, 2);
		*optarg = REALLOC(*optarg, 4);

		if(!longarg) {
			logprintf(LOG_ERR, "out of memory");
			exit(EXIT_FAILURE);
		}
		if(!shortarg) {
			logprintf(LOG_ERR, "out of memory");
			exit(EXIT_FAILURE);
		}
		if(!*optarg) {
			logprintf(LOG_ERR, "out of memory");
			exit(EXIT_FAILURE);
		}

		/* The memory to null */
		memset(*optarg, '\0', 4);
		memset(shortarg, '\0', 2);
		memset(longarg, '\0', 4);

		/* Check if the CLI character contains an equals to (=) sign.
		   If it does, we have probably encountered a long argument */
		if(strchr(argv[getOptPos],'=')) {
			/* Copy all characters until the equals to sign.
			   This will probably be the name of the argument */
			longarg = REALLOC(longarg, strcspn(argv[getOptPos],"=")+1);
			if(!longarg) {
				logprintf(LOG_ERR, "out of memory");
				exit(EXIT_FAILURE);
			}
			memset(longarg, '\0', strcspn(argv[getOptPos],"=")+1);
			memcpy(longarg, &argv[getOptPos][0], strcspn(argv[getOptPos],"="));

			/* Then copy everything after the equals sign.
			   This will probably be the value of the argument */
			size_t i = strlen(&argv[getOptPos][strcspn(argv[getOptPos],"=")+1]);
			*optarg = REALLOC(*optarg, i+1);
			if(!*optarg) {
				logprintf(LOG_ERR, "out of memory");
				exit(EXIT_FAILURE);
			}
			memset(*optarg, '\0', i+1);
			memcpy(*optarg, &argv[getOptPos][strcspn(argv[getOptPos],"=")+1], i);
		} else {
			/* If the argument does not contain a equals sign.
			   Store the argument to check later if it's a long argument */
			longarg = REALLOC(longarg, strlen(argv[getOptPos])+1);
			if(!longarg) {
				logprintf(LOG_ERR, "out of memory");
				exit(EXIT_FAILURE);
			}
			strcpy(longarg, argv[getOptPos]);
		}

		/* A short argument only contains of two characters.
		   So only store the first two characters */
		shortarg = REALLOC(shortarg, strlen(argv[getOptPos])+1);
		if(!shortarg) {
			logprintf(LOG_ERR, "out of memory");
			exit(EXIT_FAILURE);
		}
		memset(shortarg, '\0', 3);
		strncpy(shortarg, argv[getOptPos], 2);

		/* Check if the short argument and the long argument are equal,
		   then we probably encountered a short argument. Only store the
		   identifier character. If there are more CLI characters
		   after the current one, store it as the CLI value. However, only
		   do this if the first character of the argument doesn't contain*/
		if(strcmp(longarg, shortarg) == 0 && (getOptPos+1)<argc && argv[getOptPos+1][0] != '-') {
			*optarg = REALLOC(*optarg, strlen(argv[getOptPos+1])+1);
			if(!*optarg) {
				logprintf(LOG_ERR, "out of memory");
				exit(EXIT_FAILURE);
			}
			strcpy(*optarg, argv[getOptPos+1]);
			c = shortarg[1];
			getOptPos++;
		} else {
			/* If the short argument and the long argument are not equal,
			    then we probably encountered a long argument. */
			if(longarg[0] == '-' && longarg[1] == '-') {
				if((gctmp = REALLOC(gctmp, strlen(&longarg[2])+1)) == NULL) {
					logprintf(LOG_ERR, "out of memory");
					exit(EXIT_FAILURE);
				}
				strcpy(gctmp, &longarg[2]);

				/* Retrieve the short identifier for the long argument */
				if(options_get_id(opt, gctmp, &itmp) == 0) {
					c = itmp;
				} else if(argv[getOptPos][0] == '-') {
					c = shortarg[1];
				}
			} else if(argv[getOptPos][0] == '-' && strstr(shortarg, longarg) != 0) {
				c = shortarg[1];
			}
		}

		/* Check if the argument was expected */
		if(options_get_name(opt, c, &ctmp) != 0 && c > 0) {
			if(error_check == 1) {
				if(strcmp(longarg,shortarg) == 0) {
					if(shortarg[0] == '-') {
						logprintf(LOG_ERR, "invalid option -- '-%c'", c);
					} else {
						logprintf(LOG_ERR, "invalid option -- '%s'", longarg);
					}
				} else {
					logprintf(LOG_ERR, "invalid option -- '%s'", longarg);
				}
				goto gc;
			} else {
				return 0;
			}
		/* Check if an argument cannot have an argument that was set */
		} else if(strlen(*optarg) != 0 && options_get_argtype(opt, c, &itmp) == 0 && itmp == 1) {
			if(error_check == 1) {
				if(strcmp(longarg,shortarg) == 0) {
					logprintf(LOG_ERR, "option '-%c' doesn't take an argument", c);
				} else {
					logprintf(LOG_ERR, "option '%s' doesn't take an argument", longarg);
				}
				goto gc;
			} else {
				return 0;
			}
		/* Check if an argument required a value that wasn't set */
		} else if(strlen(*optarg) == 0 && options_get_argtype(opt, c, &itmp) == 0 && itmp == 2) {
			if(error_check == 1) {
				if(strcmp(longarg, shortarg) == 0) {
					logprintf(LOG_ERR, "option '-%c' requires an argument", c);
				} else {
					logprintf(LOG_ERR, "option '%s' requires an argument", longarg);
				}
				goto gc;
			} else {
				return 0;
			}
		/* Check if we have a valid argument */
		} else if(c == 0) {
			if(error_check == 1) {
				if(shortarg[0] == '-' && strstr(shortarg, longarg) != 0) {
					logprintf(LOG_ERR, "invalid option -- '-%c'", c);
				} else {
					logprintf(LOG_ERR, "invalid option -- '%s'", longarg);
				}
				goto gc;
			} else {
				return 0;
			}
		} else {
			/* If the argument didn't have a value, set it to 1 */
			if(strlen(*optarg) == 0) {
				options_set_string(opt, c, "1");
			} else {
#ifndef __FreeBSD__
				if(error_check != 2) {
					/* If the argument has a regex mask, check if it passes */
					if(options_get_mask(opt, c, &mask) == 0) {
						reti = regcomp(&regex, mask, REG_EXTENDED);
						if(reti) {
							logprintf(LOG_ERR, "could not compile regex");
							goto gc;
						}
						reti = regexec(&regex, *optarg, 0, NULL, 0);
						if(reti == REG_NOMATCH || reti != 0) {
							if(error_check == 1) {
								if(shortarg[0] == '-') {
									logprintf(LOG_ERR, "invalid format -- '-%c'", c);
								} else {
									logprintf(LOG_ERR, "invalid format -- '%s'", longarg);
								}
								logprintf(LOG_ERR, "requires %s", mask);
							}
							regfree(&regex);
							goto gc;
						}
						regfree(&regex);
					}
				}
#endif
				options_set_string(opt, c, *optarg);
			}
			return c;
		}
	}

gc:
	getOptPos=0;
	FREE(*optarg);

	return -2;
}