genutils.c

来自「一套客户/服务器模式的备份系统代码,跨平台,支持linux,AIX, IRIX,」· C语言 代码 · 共 2,504 行 · 第 1/3 页

C
2,504
字号
	  *sptr = RENEWP(*sptr, UChar, newlen);	  n_all = newlen;	}	cptr = *sptr;    }    else{	cptr = *sptr = NEWP(UChar, newlen);	n_all = newlen;	if(cptr)	  cptr[0] = '\0';    }    if(!cptr)	return(-1);    strcpy(cptr + slen, piece);    slen += plen;    if(newlen > 1 && plen > 0)      if(piece[plen - 1] == '\n' ||		(cptr[newlen - 2] != '\n' && plen < PSIZE - 1))	break;  }  if(num_alloced)    *num_alloced = n_all;  return(got_sth ? 0 : -1);}Int32wait_for_input(int fd, Int32 timeout){  fd_set		fds;  struct timeval	tv;  int	i;  FD_ZERO(&fds);  FD_SET(fd, &fds);  SETZERO(tv);  tv.tv_sec = timeout;  i = select(fd + 1, &fds, NULL, NULL, &tv);  return(i > 0 ? (FD_ISSET(fd, &fds) ? 1 : 0) : i);}Int32read_with_timeout(int fd, UChar * buf, Int32 n, Int32 timeout){  if(timeout > 0){    if(wait_for_input(fd, timeout) < 1)	return(-1);  }  return(read_forced(fd, buf, n));}void *ba_search(  void		*key,  void		*base,  Uns32		nel,  Uns32		size,  Int32		(*comp)(void *, void *)){  UChar		*ptr, *eptr, *bptr;  Int32		act_idx, i, d, prev, prev_d;  if(! key || ! base || ! nel || ! size || ! comp)    return(NULL);  act_idx = ((nel - 1) >> 1) + 1;  prev_d = d = ((act_idx - 1) >> 1) + 1;  prev = 0;  bptr = (UChar *) base;  eptr = bptr + size * (nel - 1);  i = comp(key, base);  if(! i)    return(base);  if(i < 0)    return(NULL);  i = comp(key, eptr);  if(i >= 0)    return(eptr);  forever{    ptr = bptr + (act_idx - 1) * size;    i = comp(key, ptr);    if(i == 0)	return(ptr);    if(((prev > 0 && i < 0) || (prev < 0 && i > 0)) && prev_d <= 1)	return(i < 0 ? ptr - size : ptr);    prev = i;    if(i > 0){	act_idx += d;	if(act_idx > nel){	  if(d == 1)	    return(ptr);	  act_idx -= d;	  i = nel - act_idx - 1;	  if(i <= 1)	    return(ptr);	  d = (i >> 1) + 1;	  act_idx += d;	  if(act_idx > nel){	    fprintf(stderr, compiler_error);	    exit(0);	  }	}    }    else{	act_idx -= d;	if(act_idx < 1){	  if(d == 1)	    return(NULL);	  act_idx += d;	  d = ((act_idx - 1) >> 1) + 1;	  act_idx -= d;	  if(act_idx < 1){	    fprintf(stderr, compiler_error);	    exit(0);	  }	}    }    prev_d = d;    d = ((d - 1) >> 1) + 1;    if(!d)	return(NULL);  }  return(NULL);}/* * removes all leading and trailing space (if any) from str */voidmassage_string(UChar * str){  UChar		*c1;  c1 = str;  while(isspace(*c1) && *c1)    c1++;  if(! *c1){    *str = '\0';    return;  }  while(*c1)    *(str++) = *(c1++);  do{    *(str--) = '\0';  } while(isspace(*str));}/* * On success returns a malloc'd string the contents of which is the * concatenation of string1 and string2.  Returns NULL on failure. */UChar *strapp(UChar * string1, UChar * string2){  UChar		*newstr;  newstr = (UChar *) malloc_forced((strlen(string1) + strlen(string2) + 1)				* sizeof(UChar));  if(!newstr)    return(NULL);  strcpy(newstr, string1);  strcat(newstr, string2);  return(newstr);}/* * Take a list of strings and return a malloc'd string which is the  * concatenation of all the arguments. The list of arguments must * be terminated with a NULL to indicate, that the end of the list * is reached */UChar *strchain(UChar * str, ...){  UChar		*newstr;  Int32		len;  va_list	args;  va_start(args, str);  if(!str)    GETOUT;  str = strdup(str);  if(!str)    GETOUT;  while( (newstr = va_arg(args, UChar *)) ){    len = strlen(str) + strlen(newstr) + 1;    str = RENEWP(str, UChar, len);    if(!str)	break;    strcat(str, newstr);  } getout:  va_end(args);  return(str);}UChar *			/* replace pattern by substitute in string */repl_substring(UChar * string, UChar * pattern, UChar * substitute){  UChar	*result, *subst, *walking, *newone, *working;  working = (UChar *) strdup(string);  if(!working)    return(NULL);  result = (UChar *) strdup("");  if(!result){    free(working);    return(NULL);  }  walking = working;  while( (subst = strstr(walking, pattern)) ){    *subst = '\0';    newone = strapp(result, walking);    *subst = pattern[0];    free(result);    if(!newone){	free(working);	return(NULL);    }    result = strapp(newone, substitute);    free(newone);    if(!result){	free(working);	return(NULL);    }    walking = subst + strlen(pattern);  }  newone = strapp(result, walking);  free(result);  free(working);  if(! newone)    return(NULL);  return(newone);}Int32repl_substrings(UChar ** str, ReplSpec * repls, Int32 n){  UChar	*cptr;  Int32	i;  if(!str){    errno = EINVAL;    return(-1);  }  if(! (*str) || !repls || n < 1)    return(0);  for(i = 0; i < n; i++){    if(strstr(*str, repls[i].token)){      cptr = repl_substring(*str, repls[i].token,		repls[i].repl ? repls[i].repl : *(repls[i].replptr));      if(!cptr)	return(-1);      free(*str);      *str = cptr;    }  }  return(0);}/* * Takes the string <str> and stores into <wordsp> an array of strings * where each array entry is one word from <str>.  Words are sequences * of non-whitespace characters.  This function doesn't know anything about * quoting. * * On success, returns the number of words in the array, -1 on error. */Int32str2words(UChar *** wordsp, UChar * str){  Int32		i, w;  UChar		**words = NULL, *cptr, *strc = NULL, c;  if(!wordsp || !str){    errno = EINVAL;    return(-1);  }  w = word_count(str);  words = NEWP(UChar *, w + 1);  memset(words, 0, sizeof(UChar *) * (w + 1));  strc = strdup(str);  if(!words || !strc)    GETOUT;  cptr = strc;  for(i = 0; i < w; i++){    while(isspace(*cptr) && *cptr)	cptr++;    if(! *cptr)	break;    str = cptr;    while(!isspace(*cptr) && *cptr)	cptr++;    c = *cptr;    *cptr = '\0';    words[i] = strdup(str);    if(!words[i])	GETOUT;    *cptr = c;  }  free(strc);  *wordsp = words;  return(w); getout:  if(strc)    free(strc);  if(words){    for(i = 0; i < w; i++)	if(words[i])	  free(words[i]);    free(words);  }  return(-1);}/* same like str2words, but quoting "..." is allowed in <str> to put several * non-whitespace sequences together into one word */Int32str2wordsq(UChar *** wordsp, UChar * str){  UChar		*buf = NULL, *cptr;  UChar		**words = NULL, **w;  Int32		ret = 0, n;  if(!wordsp || !str){    errno = EINVAL;    GETOUT;  }  buf = strdup(str);  if(!buf)    GETOUT;  words = NEWP(UChar *, 1);  if(!words)    GETOUT;  *words = NULL;  cptr = str;  n = 0;  while( (cptr = sscanwordq(cptr, buf)) ){    words = RENEWP(words, UChar *, n + 2);    if(!words)	GETOUT;    words[n + 1] = NULL;    words[n] = strdup(buf);    if(!words[n])	GETOUT;    n++;  }  ret = n;  *wordsp = words; cleanup:  if(buf)    free(buf);  return(ret); getout:  ret = -1;  if(words){    for(w = words; *w; w++)	free(*w);    free(words);  }  CLEANUP;}voidsscancchars(UChar * source, UChar * target){  UChar		c, a;  int		i;  while(*source){    if(*source != '\\'){	*(target++) = *(source++);	continue;    }    else{	source++;	switch(*source){	  case 'a':	    c = '\a';	    break;	  case 'b':	    c = '\b';	    break;	  case 'n':	    c = '\n';	    break;	  case 'f':	    c = '\f';	    break;	  case 'r':	    c = '\r';	    break;	  case 't':	    c = '\t';	    break;	  case 'v':	    c = '\v';	    break;	  default:	    if(*source >= '0' && *source <= '7'){		c = 0;		for(i = 0; i < 3; i++){		  if(c > 037)		    break;		  a = source[i];		  if(a > '7' || a < '0')		    break;		  c = (c << 3) | (a - '0');		}		source += i - 1;	    }	    else{		c = *source;	    }	}	source++;	*(target++) = c;    }  }  *target = '\0';}UChar *sscancstr(UChar * source, UChar * target){  UChar		*str, *cptr, *cptr2, escaped;  if(*source != '\"'){    errno = EINVAL;    return(NULL);  }  source++;  for(cptr = strchr(source, '\"'); cptr; cptr = strchr(cptr + 1, '\"')){    escaped = 0;    for(cptr2 = cptr - 1; cptr2 >= source; cptr2--){      if(*cptr2 == '\\')	escaped = ! escaped;      else	break;    }    if(!escaped)	break;  }  if(!cptr){    errno = EINVAL;    return(NULL);  }  if(! (str = strdup(source)))    return(NULL);  str[cptr - source] = '\0';  sscancchars(str, target);  free(str);  return(source + 1);}Int8escaped(UChar * str, UChar * c, UChar escc){  Int8		escaped = 0;  if(!str || !c || c < str || c >= str + strlen(str)){    errno = EINVAL;    return(-1);  }  if(!escc)    escc = '\\';  while(c > str){    c--;    if(*c == escc){	escaped = !escaped;    }    else	break;  }  return(escaped);}Uns8parity_byte(UChar * str, Int32 num){  Uns32		sum;  for(sum = 0; num > 0; num--)    sum += (Uns32) *(str++);  return((Uns8)(sum & 0xff));}static Int32_cmd2argv_(char *** argvp, char * cmd, UChar flags){  UChar		**words, *cptr, *cptr2, quoted, fullpath;  Int32		i, w;  quoted = flags & 1;  fullpath = flags & 2;  w = word_count(cmd);  if(w < 1){    errno = EINVAL;    return(-1);  }  if(quoted)    w = str2wordsq(&(words), (UChar *) cmd);  else    w = str2words(&(words), (UChar *) cmd);  if(w < 0)    return(w);  words = (UChar **) realloc_forced(words, sizeof(UChar *) * (w + 2));  if(!words)    return(-1);  words[w + 1] = NULL;  for(i = w - 1; i >= 0; i--)    words[i + 1] = words[i];  if(fullpath)    words[1] = strdup(words[0]);  else{    cptr = FN_LASTDIRDELIM(words[0]);    if(cptr)	cptr2 = strdup(cptr + 1);    else      cptr2 = strdup(words[1]);    if(cptr2)	words[1] = cptr2;    else{      if(cptr)	words[1] = cptr + 1;    }  }  *argvp = (char **) words;  return(0);}Int32cmd2argv(char *** argvp, char * cmd){  return(_cmd2argv_(argvp, cmd, 0));}Int32cmd2argvq(char *** argvp, char * cmd){  return(_cmd2argv_(argvp, cmd, 1));}Int32cmd2argvf(char *** argvp, char * cmd){  return(_cmd2argv_(argvp, cmd, 2 + 0));}Int32cmd2argvqf(char *** argvp, char * cmd){  return(_cmd2argv_(argvp, cmd, 2 + 1));}/* compare functions */Int32cmp_UCharPTR(void * p1, void * p2){  return(strcmp(*((char **) p1), *((char **) p2)));}#define	intcmp(type)				\Int32						\cmp_##type(void * p1, void * p2)		\{						\  return(*((type *) p1) - *((type *) p2));	\}intcmp(Int32)intcmp(Int16)intcmp(Int8)intcmp(SChar)#define	unscmp(type)					\Int32							\cmp_##type(void * p1, void * p2)			\{							\  return(*((type *) p1) == *((type *) p2) ? 0 :		\	(*((type *) p1) > *((type *) p2) ? 1 : -1));	\}unscmp(Uns32)unscmp(Uns16)unscmp(Uns8)unscmp(UChar)Int32cmp_Uns32Ranges(void * p1, void * p2){  return((Int32)(((Uns32Range *)p1)->first) - (Int32)(((Uns32Range *)p2)->last));}Int32compare_version_strings(UChar * v1, UChar * v2){  int		i1, i2, n1, n2, i, j;  forever{    i = sscanf(v1, "%d%n", &i1, &n1);    j = sscanf(v2, "%d%n", &i2, &n2);    if(i < 1 && j < 1)	return(0);    if(i < 1)	return(-1);    if(j < 1)	return(1);    if(i1 > i2)	return(1);    if(i2 > i1)	return(-1);    v1 += n1;    v2 += n2;    while(isalpha(*v1) && isalpha(*v2)){	if(tolower(*v1) > tolower(*v2))	  return(1);	if(tolower(*v1) < tolower(*v2))	  return(-1);	v1++;	v2++;    }    if(isalpha(*v1))	return(1);    if(isalpha(*v2))	return(-1);    if(!(*v1) && !(*v2))	return(0);    if(!(*v1))	return(-1);    if(!(*v2))	return(1);    if(isdigit(*v1) && isdigit(*v2))	continue;    if(isdigit(*v1))	return(1);    if(isdigit(*v2))	return(-1);    while(!isalnum(*v1) && *v1)	v1++;    while(!isalnum(*v2) && *v2)	v2++;    if(!(*v1) && !(*v2))	return(0);    if(!(*v1))	return(-1);    if(!(*v2))	return(1);  }  return(-1000);}static UChar	*chars64 = "0123456789+-"			"abcdefghijklmnopqrstuvwxzy"			"ABCDEFGHIJKLMNOPQRSTUVWXZY";UCharchar64(Int32 n){  if(n > 64 || n < 0)    return('\0');  return(chars64[n]);}Int32ugids_from_str(  UChar		*str,  uid_t		*uid,  gid_t		*gid,  int		*ngids,  gid_t		**gids){  int		luid, lgid, i1, n1, lngids = 0;  gid_t		*lgids = NULL;  Int32		r = 0;  luid = lgid = -1;  sscanf(str, "%d:%d%n", &luid, &lgid, &n1);  if(lgid == -1)    CLEANUPR(-1);  str += n1;  while(*str){    i1 = -1;    sscanf(str, ":%d%n", &i1, &n1);    if(i1 == -1 && *str)	CLEANUPR(-2);    if(!(lgids = ZRENEWP(lgids, gid_t, lngids + 1)))	CLEANUPR(-3);    lgids[lngids] = i1;    lngids++;    str += n1;  }  if(uid)    *uid = luid;  if(gid)    *gid = lgid;  if(ngids)    *ngids = lngids;  if(gids){    *gids = lgids;    lgids = NULL;  } cleanup:  ZFREE(lgids);  return(r);}UChar *str_from_ugids(uid_t uid, gid_t gid, int ngids, gid_t * gids){  UChar		*uidstr = NULL;  Int32		i;  if(!(uidstr = NEWP(UChar, (2 + ngids) * 20)))    return(NULL);  sprintf(uidstr, "%d:%d", (int) uid, (int) gid);  for(i = 0; i < ngids; i++)    sprintf(uidstr + strlen(uidstr), ":%d", (int) gids[i]);  return(uidstr);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?