xrxs/server/util.c

249 lines
No EOL
4.3 KiB
C

#include <u.h>
#include <sys/stat.h>
#include <libc.h>
#include <stdio.h>
#include "cart.h"
#include "util.h"
uvlong hash(char* str, int array_sz) {
uvlong h;
uchar* p;
h = 0;
for (p = (unsigned char*)str; *p != '\0'; p++)
h = 37 * h + *p;
if (array_sz == 0)
return h;
else
return h % array_sz;
}
char clca(char c) {
return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c;
} /* char to lowercase */
char cuca(char c) {
return c >= 'a' && c <= 'z' ? c - ('a' - 'A') : c;
} /* char to uppercase */
int slen(char* s) {
int i = 0;
while (s[i] && s[++i]) {
;
}
return i;
} /* string length */
char* st__(char* s, char (*fn)(char)) {
int i = 0;
char c;
while ((c = s[i]))
s[i++] = fn(c);
return s;
}
char* stuc(char* s) { return st__(s, cuca); } /* string to uppercase */
char* stlc(char* s) { return st__(s, clca); } /* string to lowercase */
char* scpy(char* src, char* dst, int len) {
int i = 0;
while ((dst[i] = src[i]) && i < len - 2)
i++;
dst[i + 1] = '\0';
return dst;
} /* string copy */
int scmp(char* a, char* b) {
int i = 0;
while (a[i] == b[i])
if (!a[i++])
return 1;
return 0;
} /* string compare */
char* scsw(char* s, char a, char b) {
int i = 0;
char c;
while ((c = s[i]))
s[i++] = c == a ? b : c;
return s;
} /* string char swap */
char* scat(char* dst, const char* src) {
char* ptr = dst + slen(dst);
while (*src)
*ptr++ = *src++;
*ptr = '\0';
return dst;
} /* string cat */
int ssin(char* s, char* ss) {
int a = 0, b = 0;
while (s[a]) {
if (s[a] == ss[b]) {
if (!ss[b + 1])
return a - b;
b++;
} else
b = 0;
a++;
}
return -1;
} /* string substring index */
char* ccat(char* dst, char c) {
int len = slen(dst);
dst[len] = c;
dst[len + 1] = '\0';
return dst;
}
Blob* read_bytes(char* path) {
FILE* f;
char* buf;
long count;
Blob* self;
f = fopen(path, "rb");
if (f == nil)
return nil;
fseek(f, 0, SEEK_END);
count = ftell(f);
rewind(f);
buf = malloc(count * sizeof(char));
if (!fread(buf, count, 1, f)) {
fclose(f);
return nil;
} else {
fclose(f);
self = malloc(sizeof(Blob));
self->data = buf;
self->length = count;
return self;
}
}
Blob* read_chars(char* path) {
FILE* f;
char* buf;
long count;
Blob* self;
f = fopen(path, "r");
if (f == nil)
return nil;
fseek(f, 0, SEEK_END);
count = ftell(f);
rewind(f);
buf = malloc(count * sizeof(char));
if (!fread(buf, count, 1, f)) {
fclose(f);
return nil;
} else {
fclose(f);
self = malloc(sizeof(Blob));
self->data = buf;
self->length = count;
return self;
}
}
int issymlink(char* name) {
struct stat s;
return lstat(name, &s) >= 0 && S_ISLNK(s.st_mode);
}
int rm_dir(char* f) {
char* name;
int fd, i, j, n, ndir, nname;
Dir* dirbuf;
int fail = 0;
fd = open(f, OREAD);
if (fd < 0) {
return 0;
}
n = dirreadall(fd, &dirbuf);
close(fd);
if (n < 0) {
return 0;
}
nname = strlen(f) + 1 + STATMAX + 1; /* plenty! */
name = malloc(nname);
if (name == 0) {
return 0;
}
ndir = 0;
for (i = 0; i < n; i++) {
snprint(name, nname, "%s/%s", f, dirbuf[i].name);
if (remove(name) != -1 || issymlink(name))
dirbuf[i].qid.type = QTFILE; /* so we won't recurse */
else {
if (dirbuf[i].qid.type & QTDIR)
ndir++;
else
fail = 1;
}
}
if (ndir)
for (j = 0; j < n; j++)
if (dirbuf[j].qid.type & QTDIR) {
snprint(name, nname, "%s/%s", f, dirbuf[j].name);
rmdir(name);
}
if (remove(f) == -1)
fail = 1;
free(name);
free(dirbuf);
return fail ? 0 : 1;
}
void strreverse(char* begin, char* end) {
char aux;
while (end > begin)
aux = *end, *end-- = *begin, *begin++ = aux;
}
void itoa(int value, char* str, int base) {
static char num[] = "0123456789abcdefghijklmnopqrstuvwxyz";
char* wstr = str;
int sign;
// Validate base
if (base < 2 || base > 35) {
*wstr = '\0';
return;
}
// Take care of sign
if ((sign = value) < 0)
value = -value;
// Conversion. Number is reversed.
do
*wstr++ = num[value % base];
while (value /= base);
if (sign < 0)
*wstr++ = '-';
*wstr = '\0';
// Reverse string
strreverse(str, wstr - 1);
}