File:  [ELWIX - Embedded LightWeight unIX -] / libaitio / src / aitio.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 23 22:54:52 2010 UTC (14 years, 4 months ago) by misho
Branches: MAIN
CVS tags: HEAD
Initial revision

    1: /*************************************************************************
    2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
    3: *  by Michael Pounov <misho@openbsd-bg.org>
    4: *
    5: * $Author: misho $
    6: * $Id: aitio.c,v 1.1 2010/02/23 22:54:52 misho Exp $
    7: *
    8: *************************************************************************/
    9: #include "global.h"
   10: 
   11: 
   12: #pragma GCC visibility push(hidden)
   13: 
   14: int io_Errno;
   15: char io_Error[STRSIZ];
   16: 
   17: #pragma GCC visibility pop
   18: 
   19: 
   20: // io_GetErrno() Get error code of last operation
   21: inline int io_GetErrno()
   22: {
   23: 	return io_Errno;
   24: }
   25: 
   26: // io_GetError() Get error text of last operation
   27: inline const char *io_GetError()
   28: {
   29: 	return io_Error;
   30: }
   31: 
   32: // io_SetErr() Set error to variables for internal use!!!
   33: inline void io_SetErr(int eno, char *estr, ...)
   34: {
   35: 	va_list lst;
   36: 
   37: 	io_Errno = eno;
   38: 	memset(io_Error, 0, STRSIZ);
   39: 	va_start(lst, estr);
   40: 	vsnprintf(io_Error, STRSIZ, estr, lst);
   41: 	va_end(lst);
   42: }
   43: 
   44: 
   45: /*
   46:  * ioPromptRead() Read data from input h[0] with prompt to output h[1]
   47:  * @h = file handles h[0] = input, h[1] = output, if NULL use stdin, stdout
   48:  * @csPrompt = Prompt before input, may be NULL
   49:  * @psData = Readed data
   50:  * @dataLen = Length of data
   51:  * return: 0 EOF; -1 error:: can`t read; >0 count of readed chars
   52: */
   53: int ioPromptRead(int *h, const char *csPrompt, char * __restrict psData, int dataLen)
   54: {
   55: 	int ok = 0;
   56: 	FILE *inp, *out;
   57: 	char szLine[BUFSIZ], *pos;
   58: 
   59: 	if (!psData || !dataLen)
   60: 		return -1;
   61: 
   62: 	inp = fdopen(!h ? 0 : h[0], "r");
   63: 	if (!inp) {
   64: 		LOGERR;
   65: 		return -1;
   66: 	}
   67: 	out = fdopen(!h ? 1 : h[1], "w");
   68: 	if (!out) {
   69: 		LOGERR;
   70: 		return -1;
   71: 	}
   72: 
   73: 	while (!ok) {
   74: 		if (csPrompt) {
   75: 			fprintf(out, "%s", csPrompt);
   76: 			fflush(out);
   77: 		}
   78: 
   79: 		memset(szLine, 0, BUFSIZ);
   80: 		if (!fgets(szLine, BUFSIZ, inp)) {
   81: 			clearerr(inp);
   82: 			fpurge(out);
   83: 			fflush(out);
   84: 			return 0;
   85: 		}
   86: 
   87: 		if ((pos = strchr(szLine, '\n')))
   88: 			*pos = 0;
   89: 
   90: 		strlcpy(psData, szLine, dataLen);
   91: 		ok = 1;
   92: 	}
   93: 
   94: 	return pos - szLine;
   95: }
   96: 
   97: /*
   98:  * ioPromptPassword() Read password from input h[0] with prompt to output h[1]
   99:  * @h = file handles h[0] = input, h[1] = output, if NULL use stdin, stdout
  100:  * @csPrompt = Prompt before input, may be NULL
  101:  * @psPass = Readed password
  102:  * @passLen = Length of password
  103:  * @confirm = Confirm password, 0 - get password, !=0 Ask for confirmation
  104:  * return: 0 EOF; -1 error:: can`t read; >0 count of readed chars
  105: */
  106: int ioPromptPassword(int *h, const char *csPrompt, char * __restrict psPass, int passLen, int confirm)
  107: {
  108: 	int ret, ok = 0;
  109: 	FILE *inp, *out;
  110: 	char szLine[2][STRSIZ];
  111: 	struct sgttyb tty_state;
  112: 
  113: 	if (!psPass || !passLen)
  114: 		return -1;
  115: 
  116: 	inp = fdopen(!h ? 0 : h[0], "r");
  117: 	if (!inp) {
  118: 		LOGERR;
  119: 		return -1;
  120: 	}
  121: 	out = fdopen(!h ? 1 : h[1], "w");
  122: 	if (!out) {
  123: 		LOGERR;
  124: 		return -1;
  125: 	}
  126: 
  127: 	if (ioctl(fileno(inp), TIOCGETP, &tty_state) == -1) {
  128: 		LOGERR;
  129: 		return -1;
  130: 	} else {
  131: 		tty_state.sg_flags &= ~ECHO;
  132: 		if (ioctl(fileno(inp), TIOCSETP, &tty_state) == -1) {
  133: 			LOGERR;
  134: 			return -1;
  135: 		}
  136: 	}
  137: 
  138: 	while (!ok) {
  139: 		switch ((ret = ioPromptRead(h, (!csPrompt || !*csPrompt) ? "Password:" : csPrompt, 
  140: 						szLine[0], STRSIZ))) {
  141: 			case -1:
  142: 				LOGERR;
  143: 				ok = -1;
  144: 			case 0:
  145: 				goto next;
  146: 		}
  147: 		if (confirm) {
  148: 			fprintf(out, "\n");
  149: 			fflush(out);
  150: 
  151: 			switch (ioPromptRead(h, "Password confirm:", szLine[1], STRSIZ)) {
  152: 				case -1:
  153: 					LOGERR;
  154: 					ok = -1;
  155: 					goto next;
  156: 				case 0:
  157: 				default:
  158: 					if (strcmp(szLine[0], szLine[1])) {
  159: 						fprintf(out, "\n\07\07Mismatch - Try again!\n");
  160: 						fflush(out);
  161: 						continue;
  162: 					}
  163: 			}
  164: 		}
  165: 
  166: 		strlcpy(psPass, szLine[0], passLen);
  167: 		ok = ret;
  168: 		fprintf(out, "\n");
  169: 		fflush(out);
  170: 	}
  171: 
  172: next:
  173: 	tty_state.sg_flags |= ECHO;
  174: 	if (ioctl(fileno(inp), TIOCSETP, &tty_state) == -1) {
  175: 		LOGERR;
  176: 		return -1;
  177: 	}
  178: 
  179: 	return ok;
  180: }
  181: 
  182: /*
  183:  * ioRegexVerify() Function for verify data match in regex expression
  184:  * @csRegex = Regulare expression pattern
  185:  * @csData = Data for check and verify
  186:  * @startPos = Return start positions
  187:  * @endPos = Return end positions
  188:  * return: NULL not match or error; !=NULL begin of matched data
  189: */
  190: const char *ioRegexVerify(const char *csRegex, const char *csData, int *startPos, int *endPos)
  191: {
  192: 	regex_t re;
  193: 	regmatch_t match;
  194: 	char szErr[STRSIZ];
  195: 	int ret, flg;
  196: 	const char *pos;
  197: 
  198: 	if (!csRegex || !csData)
  199: 		return NULL;
  200: 
  201: 	if ((ret = regcomp(&re, csRegex, REG_EXTENDED))) {
  202: 		regerror(ret, &re, szErr, STRSIZ);
  203: 		io_SetErr(ret, "Error:: %s\n", szErr);
  204: 		regfree(&re);
  205: 		return NULL;
  206: 	}
  207: 
  208: 	for (ret = flg = 0, pos = csData; !(ret = regexec(&re, pos, 1, &match, flg)); 
  209: 			pos += match.rm_eo, flg = REG_NOTBOL) {
  210: 		if (startPos)
  211: 			*startPos = match.rm_so;
  212: 		if (endPos)
  213: 			*endPos = match.rm_eo;
  214: 
  215: 		pos += match.rm_so;
  216: 		break;
  217: 	}
  218: 
  219: 	if (ret) {
  220: 		regerror(ret, &re, szErr, STRSIZ);
  221: 		io_SetErr(ret, "Error:: %s\n", szErr);
  222: 		pos = NULL;
  223: 	}
  224: 
  225: 	regfree(&re);
  226: 	return pos;
  227: }
  228: 
  229: /*
  230:  * ioRegexGet() Function for get data match in regex expression
  231:  * @csRegex = Regulare expression pattern
  232:  * @csData = Data from get
  233:  * @psString = Returned string if match
  234:  * @strLen = Length of string
  235:  * return: 0 not match; >0 count of returned chars
  236: */
  237: int ioRegexGet(const char *csRegex, const char *csData, char * __restrict psString, int strLen)
  238: {
  239: 	int sp, ep, len;
  240: 	const char *str;
  241: 
  242: 	if (!csRegex || !csData)
  243: 		return -1;
  244: 
  245: 	str = ioRegexVerify(csRegex, csData, &sp, &ep);
  246: 	if (!str)
  247: 		return 0;
  248: 
  249: 	len = ep - sp;
  250: 	if (psString && strLen) {
  251: 		memset(psString, 0, strLen);
  252: 		strncpy(psString, str, strLen <= len ? strLen - 1 : len);
  253: 	}
  254: 
  255: 	return len;
  256: }
  257: 
  258: /*
  259:  * ioRegexReplace() Function for replace data match in regex expression with newdata
  260:  * @csRegex = Regulare expression pattern
  261:  * @csData = Source data
  262:  * @csNew = Data for replace
  263:  * return: NULL not match or error; !=NULL allocated new string, must be free after use!
  264: */
  265: char *ioRegexReplace(const char *csRegex, const char *csData, const char *csNew)
  266: {
  267: 	int sp, ep, len;
  268: 	char *str = NULL;
  269: 
  270: 	if (!csRegex || !csData)
  271: 		return NULL;
  272: 
  273: 	if (!ioRegexVerify(csRegex, csData, &sp, &ep))
  274: 		return NULL;
  275: 
  276: 	// ___ before match
  277: 	len = sp + 1;
  278: 	str = malloc(len);
  279: 	if (!str) {
  280: 		LOGERR;
  281: 		return NULL;
  282: 	} else
  283: 		strlcpy(str, csData, len);
  284: 	// * replace match *
  285: 	if (csNew) {
  286: 		len += strlen(csNew);
  287: 		str = realloc(str, len);
  288: 		if (!str) {
  289: 			LOGERR;
  290: 			return NULL;
  291: 		} else
  292: 			strlcat(str, csNew, len);
  293: 	}
  294: 	// after match ___
  295: 	len += strlen(csData) - ep;
  296: 	str = realloc(str, len);
  297: 	if (!str) {
  298: 		LOGERR;
  299: 		return NULL;
  300: 	} else
  301: 		strlcat(str, csData + ep, len);
  302: 
  303: 	return str;
  304: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>