#ifndef lint static char *rcs = "$Header: string.c,v 1.1 88/01/15 13:05:31 simpson Rel $"; #endif /* $Log: string.c,v $ * Revision 1.1 88/01/15 13:05:31 simpson * initial release * * Revision 0.2 87/12/18 11:35:41 simpson * added extractinteger function * * Revision 0.1 87/12/11 18:31:21 simpson * beta test * */ /* String related routines */ #include #include #include /* Return tail of a pathname (Ex: /usr/shar.c => shar.c) */ char *tail(s) char *s; { char *t; char *rindex(); return((t = rindex(s, '/')) ? ++t : s); } /* Set a certain environment variable. If the variable is already set, * it is reset. */ void setenv(variable, value) char *variable; char *value; { extern char **environ; int i; char **p, **head, **hptr; char *malloc(), *strcpy(); char temp[81]; if (!variable) return; for (i = 0, p = environ; *p; p++, i++) ; hptr = head = (char **)malloc((unsigned)((i + 2) * sizeof(char *))); for (p = environ; *p; p++) { (void)sprintf(temp, "%s=", variable); if (EQN(temp, *p, strlen(temp))) continue; *hptr++ = *p; } if (!value) (void)sprintf(temp, "%s=", variable); else (void)sprintf(temp, "%s=%s", variable, value); (void)strcpy(*hptr++ = malloc((unsigned)(strlen(temp)+1)), temp); *hptr = NULL; environ = head; } /* Returns next component from a list of ':' separated fields such as that * found in a $PATH variable. The return value is static and overwritten * after each call. The passed string value is incremented to point to the * next path. NULL is returned if there is no next component. */ char *nextcomponent(s) char **s; { static char comp[81]; int i; if (!s || !*s) return NULL; while (**s == ':') ++*s; if (**s == '\0') return NULL; for (i = 0; **s != ':' && **s != '\0'; ++*s, i++) comp[i] = **s; comp[i] = '\0'; return comp; } /* Returns an expanded file name. An expanded file name is a file name * with a preceding ~ expanded. If a name is not given after the tilde, * the current effective user id is used to look up the name and expand the * file name. */ char *expandtilde(filename) char *filename; { char pathname[81]; char name[81]; char *endptr, *index(), *strcpy(), *strncpy(), *strcat(); struct passwd *p; if (!filename || strlen(filename) == 0 || filename[0] != '~') return filename; pathname[0] = '\0'; if (filename[1] == '\0' || filename[1] == '/') { if (!(p = getpwuid(geteuid()))) return filename; if (p->pw_dir) (void)strcpy(pathname, p->pw_dir); (void)strcat(pathname, &filename[1]); } else { if (!(endptr = index(&filename[1], '/'))) (void)strcpy(name, &filename[1]); else (void)strncpy(name, &filename[1], endptr - &filename[1]); if (!(p = getpwnam(name))) return filename; if (p->pw_dir) (void)strcpy(pathname, p->pw_dir); (void)strcat(pathname, endptr); } (void)strcpy(filename, pathname); return filename; } /* Returns and expanded file name. An expanded file name is a file name * with a preceding $HOME expanded. For example, the file name * "$HOME/.login" would be expanded to "/staff1/simpson/.login" if the * current effective user id is that of simpson. */ char *expandhome(filename) char *filename; { char s[80], *strcpy(), *strcat(); struct passwd *p; if (!filename || strlen(filename) < 5 || !EQN(filename, "$HOME", 5)) return filename; if (!(p = getpwuid(geteuid()))) return filename; s[0] = '\0'; if (p->pw_dir) (void)strcpy(s, p->pw_dir); (void)strcat(s, &filename[5]); (void)strcpy(filename, s); return filename; } /* Returns the next integer contained in the string or NULL if no integers * are left. The updated string pointer is returned. */ char *extractinteger(s, i) char *s; int *i; { Boolean negative = FALSE; char *p = s; while (p && *p && (*p < '0' || *p > '9') && *p != '-') p++; if (!p || !*p) return NULL; if (*p == '-') { negative = TRUE; p++; } *i = 0; if (*p < '0' || *p > '9') return p; do { *i = *i * 10 + (*p - '0'); p++; } while ('0' <= *p && *p <= '9'); if (negative) *i = -*i; return p; }