2021-10-11 19:38:01 -03:00

385 lines
6.0 KiB
C
Executable File

#ident "@(#)string.c 1.7 95/01/14 SMI" /* From AT&T Toolchest */
/*
* string processing routines for Korn shell
*
*/
#include "defs.h"
#include "sym.h"
#ifdef MULTIBYTE
# include "national.h"
#endif /* MULTIBYTE */
extern char *utos();
/*
* converts integer n into an unsigned decimal string
*/
char *sh_itos(n)
int n;
/*@
return x satisfying atol(x)==n;
@*/
{
return(utos((ulong)n,10));
}
/*
* look for the substring <old> in <string> and replace with <new>
* The new string is put on top of the stack
*/
char *sh_substitute(string,old,new)
const char *string;
const char *old;
char *new;
/*@
assume string!=NULL && old!=NULL && new!=NULL;
return x satisfying x==NULL ||
strlen(x)==(strlen(in string)+strlen(in new)-strlen(in old));
@*/
{
register const char *sp = string;
register const char *cp;
const char *savesp = NIL;
stakseek(0);
if(*sp==0)
return(NIL);
if(*(cp=old) == 0)
goto found;
do
{
/* skip to first character which matches start of old */
while(*sp && (savesp==sp || *sp != *cp))
{
#ifdef MULTIBYTE
/* skip a whole character at a time */
int c = *sp;
c = echarset(c);
c = in_csize(c) + (c>=2);
while(c-- > 0)
#endif /* MULTIBYTE */
stakputc(*sp++);
}
if(*sp == 0)
return(NIL);
savesp = sp;
for(;*cp;cp++)
{
if(*cp != *sp++)
break;
}
if(*cp==0)
/* match found */
goto found;
sp = savesp;
cp = old;
}
while(*sp);
return(NIL);
found:
/* copy new */
stakputs(new);
/* copy rest of string */
stakputs(sp);
return(stakfreeze(1));
}
/*
* put string v onto the heap and return the heap pointer
*/
char *sh_heap(v)
register const char *v;
/*@
return x satisfying (in v? strcmp(v,x)==0: x==0);
@*/
{
register char *p;
if(v)
{
sh_copy(v,p=malloc((unsigned)strlen(v)+1));
return(p);
}
else
return(0);
}
/*
* TRIM(sp)
* Remove escape characters from characters in <sp> and eliminate quoted nulls.
*/
void sh_trim(sp)
register char * sp;
/*@
assume sp!=NULL;
promise strlen(in sp) <= in strlen(sp);
@*/
{
register char *dp;
register int c;
if(sp)
{
dp = sp;
while(c= *sp++)
{
if(c == ESCAPE)
c = *sp++;
if(c)
*dp++ = c;
}
*dp = 0;
}
}
/*
* copy string a to string b and return a pointer to the end of the string
*/
char *sh_copy(a,b)
register const char *a;
register char *b;
/*@
assume a!=NULL && b!= NULL;
promise strcmp(in a,in b)==0;
return x satisfying (x-(in b))==strlen(in a);
@*/
{
while(*b++ = *a++);
return(--b);
}
/*
* G. S. Fowler
* AT&T Bell Laboratories
*
* apply file permission expression expr to perm
*
* each expression term must match
*
* [ugo]*[-&+|=]?[rwxst0-7]*
*
* terms may be combined using ,
*
* if non-null, e points to the first unrecognized char in expr
*/
#ifndef S_IRWXU
# ifndef S_IREAD
# define S_IREAD 00400
# define S_IWRITE 00200
# define S_IEXEC 00100
# endif
# ifndef S_ISUID
# define S_ISUID 04000
# endif
# ifndef S_ISGID
# define S_ISGID 02000
# endif
# ifndef S_IRUSR
# define S_IRUSR S_IREAD
# define S_IWUSR S_IWRITE
# define S_IXUSR S_IEXEC
# define S_IRGRP (S_IREAD>>3)
# define S_IWGRP (S_IWRITE>>3)
# define S_IXGRP (S_IEXEC>>3)
# define S_IROTH (S_IREAD>>6)
# define S_IWOTH (S_IWRITE>>6)
# define S_IXOTH (S_IEXEC>>6)
# endif
#ifndef S_ISVTX
# define S_ISVTX 01000
#endif
# define S_IRWXU (S_IRUSR|S_IWUSR|S_IXUSR)
# define S_IRWXG (S_IRGRP|S_IWGRP|S_IXGRP)
# define S_IRWXO (S_IROTH|S_IWOTH|S_IXOTH)
#endif
/*
* some really old systems don't have memcpy()
*/
#ifdef NOMEMCPY
# ifdef NOBCOPY
char *memcpy(b,a,n)
char *b;
register char *a;
{
register int n;
register char *d = b;
while(n--)
*d++ = *a++;
return(b);
}
# else
char *memcpy(b,a,n)
char *b,*a;
{
bcopy(a,b,n);
return(b);
}
# endif /* NOBCOPY */
#endif /* NOMEMCPY */
#ifdef NOMEMSET
char *memset(region,c,n)
register char *region;
register int c,n;
{
register char *sp = region;
while(n--)
*sp++ = c;
return(region);
}
#endif /* NOMEMSET */
#define READ S_IRUSR|S_IRGRP|S_IROTH
#define WRITE S_IWUSR|S_IWGRP|S_IWOTH
#define EXEC S_IXUSR|S_IXGRP|S_IXOTH
#define USER S_ISVTX|S_ISUID|S_IRWXU
#define GROUP S_ISGID|S_IRWXG
#define OTHER S_IRWXO
#define ALL S_ISUID|S_ISGID|S_ISVTX|READ|WRITE|EXEC
static mode_t
who(expr, fmode)
char **expr;
register mode_t *fmode;
{
register mode_t m;
register char *maskstr = *expr;
m = 0;
for (; ; maskstr++) {
switch (*maskstr) {
case 'u':
m |= USER;
continue;
case 'g':
m |= GROUP;
continue;
case 'o':
m |= OTHER;
continue;
case 'a':
m |= ALL;
continue;
default:
if (m == 0) {
m = ALL;
if (*maskstr != '=')
m &= *fmode;
}
*expr = maskstr;
return (m);
}
}
}
static int
what(expr)
char **expr;
{
register int r;
register char *maskstr = *expr;
switch (*maskstr) {
case '+':
case '-':
case '=':
r = *maskstr++;
*expr = maskstr;
return (r);
}
return (0);
}
int
strperm(expr, e, perm)
char* expr;
char** e;
register int perm;
/*@
assume expr!=0;
assume e==0 || *e!=0;
@*/
{
char *maskstr = expr;
mode_t m, b;
mode_t om;
register int o, goon;
om = (READ|WRITE|EXEC) & perm;
do {
m = who(&maskstr, &om);
while (o = what(&maskstr)) {
b = 0;
goon = 0;
switch (*maskstr) {
case 'u':
b = (om & ((mode_t)USER)) >> 6;
goto dup;
case 'g':
b = (om & ((mode_t)GROUP)) >> 3;
goto dup;
case 'o':
b = (om & ((mode_t)OTHER));
dup:
b &= READ|WRITE|EXEC;
b |= (b << 3) | (b << 6);
maskstr++;
goon = 1;
}
while (goon == 0) {
switch (*maskstr++) {
case 'r':
b |= READ;
continue;
case 'w':
b |= WRITE;
continue;
case 'x':
b |= EXEC;
continue;
case 'X':
case 's':
continue;
default:
maskstr--;
goon = 1;
}
}
b &= m;
switch (o) {
case '+':
/* create new mode */
om |= b;
break;
case '-':
/* create new mode */
om &= ~b;
break;
case '=':
/* create new mode */
om &= ~m;
om |= b;
break;
}
}
} while (*maskstr++ == ',');
maskstr--;
*e = maskstr;
return (om);
}