File:  [ELWIX - Embedded LightWeight unIX -] / libaitio / src / aitio.c
Revision 1.1.1.1.8.2: download - view: text, annotated - select for diffs - revision graph
Fri Sep 10 12:38:26 2010 UTC (13 years, 9 months ago) by misho
Branches: io1_3
Diff to: branchpoint 1.1.1.1: preferred, unified
added new feature

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

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