diff options
Diffstat (limited to 'indep.c')
-rw-r--r-- | indep.c | 736 |
1 files changed, 736 insertions, 0 deletions
@@ -0,0 +1,736 @@ +/* $Id: indep.c,v 1.1 2001/11/08 05:15:01 a-ito Exp $ */ +#include "fm.h" +#include <stdio.h> +#include <pwd.h> +#include <sys/param.h> +#include <sys/types.h> +#include <stdlib.h> +#include "indep.h" +#include "Str.h" +#include "gc.h" +#include "myctype.h" + +#if defined(__EMX__)&&!defined(JP_CHARSET) +int CodePage=0; +#endif + +static int is_safe(int); + +struct table3 { + char *item1; + unsigned char item2; +}; + +struct table3 escapetbl[] = +{ + {"lt", '<'}, + {"gt", '>'}, + {"amp", '&'}, + {"quot", '"'}, + {"LT", '<'}, + {"GT", '>'}, + {"AMP", '&'}, + {"QUOT", '"'}, +/* for latin1_tbl */ + {"nbsp", 128 + 32}, + {"NBSP", 128 + 32}, + {"iexcl", 128 + 33}, + {"cent", 128 + 34}, + {"pound", 128 + 35}, + {"curren", 128 + 36}, + {"yen", 128 + 37}, + {"brvbar", 128 + 38}, + {"sect", 128 + 39}, + {"uml", 128 + 40}, + {"copy", 128 + 41}, + {"ordf", 128 + 42}, + {"laquo", 128 + 43}, + {"not", 128 + 44}, + {"shy", 128 + 45}, + {"reg", 128 + 46}, + {"macr", 128 + 47}, + {"deg", 128 + 48}, + {"plusmn", 128 + 49}, + {"sup2", 128 + 50}, + {"sup3", 128 + 51}, + {"acute", 128 + 52}, + {"micro", 128 + 53}, + {"para", 128 + 54}, + {"middot", 128 + 55}, + {"cedil", 128 + 56}, + {"sup1", 128 + 57}, + {"ordm", 128 + 58}, + {"raquo", 128 + 59}, + {"frac14", 128 + 60}, + {"frac12", 128 + 61}, + {"frac34", 128 + 62}, + {"iquest", 128 + 63}, + {"Agrave", 128 + 64}, + {"Aacute", 128 + 65}, + {"Acirc", 128 + 66}, + {"Atilde", 128 + 67}, + {"Auml", 128 + 68}, + {"Aring", 128 + 69}, + {"AElig", 128 + 70}, + {"Ccedil", 128 + 71}, + {"Egrave", 128 + 72}, + {"Eacute", 128 + 73}, + {"Ecirc", 128 + 74}, + {"Euml", 128 + 75}, + {"Igrave", 128 + 76}, + {"Iacute", 128 + 77}, + {"Icirc", 128 + 78}, + {"Iuml", 128 + 79}, + {"ETH", 128 + 80}, + {"Ntilde", 128 + 81}, + {"Ograve", 128 + 82}, + {"Oacute", 128 + 83}, + {"Ocirc", 128 + 84}, + {"Otilde", 128 + 85}, + {"Ouml", 128 + 86}, + {"times", 128 + 87}, + {"Oslash", 128 + 88}, + {"Ugrave", 128 + 89}, + {"Uacute", 128 + 90}, + {"Ucirc", 128 + 91}, + {"Uuml", 128 + 92}, + {"Yacute", 128 + 93}, + {"THORN", 128 + 94}, + {"szlig", 128 + 95}, + {"agrave", 128 + 96}, + {"aacute", 128 + 97}, + {"acirc", 128 + 98}, + {"atilde", 128 + 99}, + {"auml", 128 + 100}, + {"aring", 128 + 101}, + {"aelig", 128 + 102}, + {"ccedil", 128 + 103}, + {"egrave", 128 + 104}, + {"eacute", 128 + 105}, + {"ecirc", 128 + 106}, + {"euml", 128 + 107}, + {"igrave", 128 + 108}, + {"iacute", 128 + 109}, + {"icirc", 128 + 110}, + {"iuml", 128 + 111}, + {"eth", 128 + 112}, + {"ntilde", 128 + 113}, + {"ograve", 128 + 114}, + {"oacute", 128 + 115}, + {"ocirc", 128 + 116}, + {"otilde", 128 + 117}, + {"ouml", 128 + 118}, + {"divide", 128 + 119}, + {"oslash", 128 + 120}, + {"ugrave", 128 + 121}, + {"uacute", 128 + 122}, + {"ucirc", 128 + 123}, + {"uuml", 128 + 124}, + {"yacute", 128 + 125}, + {"thorn", 128 + 126}, + {"yuml", 128 + 127}, + {NULL, 0}, +}; + +#ifdef JP_CHARSET +static char *latin1_tbl[128] = +{ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0- 7 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 8- 15 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 16- 23 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 24- 31 */ + NBSP, "!", "¡ñ", "¡ò", NULL, "¡ï", "|", "¡ø", /* 32- 39 */ + "¡¯", "(C)", NULL, "¢ã", "¢Ì", "-", "(R)", "¡±", /* 40- 47 */ + "¡ë", "¡Þ", "2", "3", "'", "¦Ì", "¢ù", "¡¦", /* 48- 55 */ + ",", "1", NULL, "¢ä", "1/4", "1/2", "3/4", "?", /* 56- 63 */ + "A`", "A'", "A^", "A~", "Ae", "¢ò", "AE", "C", /* 64- 71 */ + "E`", "E'", "E^", "E", "I`", "I'", "I^", "I", /* 72- 79 */ + "D", "N~", "O`", "O'", "O^", "O~", "Oe", "¡ß", /* 80- 87 */ + "¦Õ", "U`", "U'", "U^", "Ue", "Y'", "th", "ss", /* 88- 95 */ + "a`", "a'", "a^", "a~", "ae", "a", "ae", "c", /* 96-103 */ + "e`", "e'", "e^", "e", "i`", "i'", "i^", "i", /* 104-111 */ + "dh", "n~", "o`", "o'", "o^", "o~", "oe", "¡à", /* 112-119 */ + "¦Õ", "u`", "u'", "u^", "ue", "y'", "th", "y" /* 120-127 */ +}; + +char * +conv_latin1(int ch) +{ + static char dummy[] = {0, 0}; + if (ch > 0xff) { + /* it must be a unicode character; w3m can't handle it */ + return "??"; + } + if (!IS_PRINT(ch) && !IS_CNTRL(ch)) { + char *save; + if (ch >= 0x80 && (save = latin1_tbl[ch - 0x80])) { + return save; + } + return "?"; + } + else { + dummy[0] = ch; + return dummy; + } +} +#else /* not JP_CHARSET */ +#ifdef __EMX__ +/* + * Character conversion table + * ( to code page 850 from iso-8859-1 ) + * + * Following character constants are in code page 850. + */ +static char latin1_tbl[96] = { + ' ', '\255', '\275', '\234', '\317', '\276', '\335', '\365', + '\371', '\270', '\246', '\256', '\252', '\360', '\251', '\356', + '\370', '\361', '\375', '\374', '\357', '\346', '\364', '\372', + '\367', '\373', '\247', '\257', '\254', '\253', '\363', '\250', + '\267', '\265', '\266', '\307', '\216', '\217', '\222', '\200', + '\324', '\220', '\322', '\323', '\336', '\326', '\327', '\330', + '\321', '\245', '\343', '\340', '\342', '\345', '\231', '\236', + '\235', '\353', '\351', '\352', '\232', '\355', '\350', '\341', + '\205', '\240', '\203', '\306', '\204', '\206', '\221', '\207', + '\212', '\202', '\210', '\211', '\215', '\241', '\214', '\213', + '\320', '\244', '\225', '\242', '\223', '\344', '\224', '\366', + '\233', '\227', '\243', '\226', '\201', '\354', '\347', '\230' +}; +#endif + +char * +conv_latin1(int ch) +{ + static char dummy[2] = {0, 0}; + if (ch > 0xff) { + /* it must be a unicode character; w3m can't handle it */ + return "??"; + } +#ifdef __EMX__ + { + if(CodePage==850&&ch>=160) + ch=latin1_tbl[(unsigned)ch-160]; + } +#endif + dummy[0] = ch; + return dummy; +} +#endif /* not JP_CHARSET */ + +int +getescapechar(char **s) +{ + int i, dummy = 0; + char *save; + Str tmp = Strnew(); + + save = *s; + if (**s == '&') + (*s)++; + if (**s == '#') { + if (*(*s + 1) == 'x') { + (*s)++; + sscanf(*s + 1, "%x", &dummy); + } + else if (*(*s + 1) == 'X') { + (*s)++; + sscanf(*s + 1, "%X", &dummy); + } + else { + sscanf(*s + 1, "%d", &dummy); + } + (*s)++; + save = *s; + while (**s && **s != ';') { + if (!IS_ALNUM(**s)) { + if (*s > save) + break; + else + goto fail; + } + (*s)++; + } + if (**s == ';') + (*s)++; + return dummy; + } + while (IS_ALNUM(**s)) { + Strcat_char(tmp, **s); + (*s)++; + } + /* if (**s != ';') goto fail; */ + if (**s == ';') + (*s)++; + for (i = 0; escapetbl[i].item1 != NULL; i++) + if (Strcmp_charp(tmp, escapetbl[i].item1) == 0) { + return escapetbl[i].item2; + } + fail: + return '\0'; +} + +char * +getescapecmd(char **s) +{ + char *save = *s; + Str tmp, tmp2; + int ch = getescapechar(s); + if (ch) + return conv_latin1(ch); + + tmp = Strnew_charp_n(save, *s - save); + if (tmp->ptr[0] != '&') { + tmp2 = Strnew_charp("&"); + Strcat(tmp2, tmp); + return tmp2->ptr; + } + return tmp->ptr; +} + +char * +allocStr(const char *s, int len) +{ + char *ptr; + + if (s == NULL) + return NULL; + if (len == 0) + len = strlen(s); + ptr = NewAtom_N(char, len + 1); + if (ptr == NULL) { + fprintf(stderr, "fm: Can't allocate string. Give me more memory!\n"); + exit(-1); + } + bcopy(s, ptr, len); + ptr[len] = '\0'; + return ptr; +} + +int +strCmp(const void *s1, const void *s2) +{ + unsigned char *p1 = *(unsigned char **) s1; + unsigned char *p2 = *(unsigned char **) s2; + + while ((*p1 != '\0') && (*p1 == *p2)) { + p1++; + p2++; + } + return (*p1 - *p2); +} + +void +copydicname(char *s, char *fn) +{ + strcpy(s, fn); + for (fn = &s[strlen(s)]; s < fn; fn--) { + if (*fn == '/') { + *(fn + 1) = '\0'; + return; + } + } + if (*fn == '/') + *(fn + 1) = '\0'; + else + *fn = '\0'; +} + +#ifndef __EMX__ +char * +currentdir() +{ + char *path; +#ifdef GETCWD + path = New_N(char, MAXPATHLEN); + getcwd(path, MAXPATHLEN); +#else /* not GETCWD */ +#ifdef GETWD + path = New_N(char, 1024); + getwd(path); +#else /* not GETWD */ + FILE *f; + char *p; + path = New_N(char, 1024); + f = popen("pwd", "r"); + fgets(path, 1024, f); + pclose(f); + for (p = path; *p; p++) + if (*p == '\n') { + *p = '\0'; + break; + } +#endif /* not GETWD */ +#endif /* not GETCWD */ + return path; +} +#endif /* __EMX__ */ + +char * +cleanupName(char *name) +{ + char *buf, *p, *q; + + buf = allocStr(name, 0); + p = buf; + q = name; + while (*q != '\0' && *q != '?') { + if (strncmp(p, "/../", 4) == 0) { /* foo/bar/../FOO */ + if (p - 2 == buf && strncmp(p - 2, "..", 2) == 0) { + /* ../../ */ + p += 3; + q += 3; + } + else if (p - 3 >= buf && strncmp(p - 3, "/..", 3) == 0) { + /* ../../../ */ + p += 3; + q += 3; + } + else { + while (p != buf && *--p != '/'); /* ->foo/FOO */ + *p = '\0'; + q += 3; + strcat(buf, q); + } + } + else if (strcmp(p, "/..") == 0) { /* foo/bar/.. */ + if (p - 2 == buf && strncmp(p - 2, "..", 2) == 0) { + /* ../.. */ + } + else if (p - 3 >= buf && strncmp(p - 3, "/..", 3) == 0) { + /* ../../.. */ + } + else { + while (p != buf && *--p != '/'); /* ->foo/ */ + *++p = '\0'; + } + break; + } + else if (strncmp(p, "/./", 3) == 0) { /* foo/./bar */ + *p = '\0'; /* -> foo/bar */ + q += 2; + strcat(buf, q); + } + else if (strcmp(p, "/.") == 0) { /* foo/. */ + *++p = '\0'; /* -> foo/ */ + break; + } + else if (strncmp(p, "//", 2) == 0) { /* foo//bar */ + /* -> foo/bar */ +#ifdef CYGWIN + if (p == buf) { /* //DRIVE/foo */ + p += 2; + q += 2; + continue; + } +#endif /* CYGWIN */ + *p = '\0'; + q++; + strcat(buf, q); + } + else { + p++; + q++; + } + } + return buf; +} + +/* string search using the simplest algorithm */ +char * +strcasestr(char *s1, char *s2) +{ + int len1, len2; + len1 = strlen(s1); + len2 = strlen(s2); + while (*s1 && len1 >= len2) { + if (strncasecmp(s1, s2, len2) == 0) + return s1; + s1++; + len1--; + } + return 0; +} + +static int +strcasematch(char *s1, char *s2) +{ + int x; + while (*s1) { + if (*s2 == '\0') + return 1; + x = tolower(*s1) - tolower(*s2); + if (x != 0) + break; + s1++; + s2++; + } + return (*s2 == '\0'); +} + +/* search multiple strings */ +int +strcasemstr(char *str, char *srch[], char **ret_ptr) +{ + int i; + while (*str) { + for (i = 0; srch[i]; i++) { + if (strcasematch(str, srch[i])) { + if (ret_ptr) + *ret_ptr = str; + return i; + } + } + str++; + } + return -1; +} + +char * +cleanup_str(char *str) +{ + Str tmp = NULL; + char *s = str, *c; + + while (*s) { + if (*s == '&') { + if (tmp == NULL) { + tmp = Strnew(); + Strcat_charp_n(tmp, str, s - str); + } + c = getescapecmd(&s); + Strcat_charp(tmp, c); + } + else { + if (tmp) + Strcat_char(tmp, *s); + s++; + } + } + + if (tmp) + return tmp->ptr; + else + return str; +} + +char * +remove_space(char *str) +{ + Str s = Strnew(); + while (*str) { + if (!IS_SPACE(*str)) + Strcat_char(s, *str); + str++; + } + return s->ptr; +} + +char * +htmlquote_char(char c) +{ + switch (c) { + case '&': + return "&"; + case '<': + return "<"; + case '>': + return ">"; + case '"': + return """; + } + return NULL; +} + +char * +htmlquote_str(char *str) +{ + Str tmp = NULL; + char *p, *q; + for (p = str; *p; p++) { + q = htmlquote_char(*p); + if (q) { + if (tmp == NULL) { + tmp = Strnew(); + Strcat_charp_n(tmp, str, p - str); + } + Strcat_charp(tmp, q); + } + else { + if (tmp) + Strcat_char(tmp, *p); + } + } + if (tmp) + return tmp->ptr; + else + return str; +} + +Str +form_quote(Str x) +{ + Str r = Strnew(); + int i; + char c; + for (i = 0; i < x->length; i++) { + c = x->ptr[i]; + if (c == ' ') + Strcat_char(r, '+'); + else if (IS_ALNUM(c) || is_safe(c)) { + Strcat_char(r, c); + } + else { + Strcat_charp(r, "%"); + Strcat(r, Sprintf("%02X", (c & 0xff))); + } + } + return r; +} + +/* rfc1808 safe */ +static int +is_safe(int c) +{ + switch (c) { + /* safe */ + case '$': + case '-': + case '_': + case '.': + return 1; + default: + return 0; + } +} + +Str +form_unquote(Str x) +{ + Str r = Strnew(); + int i, j; + char c; + Str num; + + for (i = 0; i < x->length; i++) { + c = x->ptr[i]; + if (c == '+') + Strcat_char(r, ' '); + else if (c == '%') { + num = Strnew_charp("0"); + if (IS_ALNUM(x->ptr[i + 1])) { + Strcat_char(num, x->ptr[i + 1]); + i++; + if (IS_ALNUM(x->ptr[i + 1])) { + Strcat_char(num, x->ptr[i + 1]); + i++; + } + } + sscanf(num->ptr, "%x", &j); + Strcat_char(r, (char) j); + } + else + Strcat_char(r, c); + } + return r; +} + +char * +expandPath(char *name) +{ + Str userName = NULL; + char *p; + struct passwd *passent, *getpwnam(const char *); + Str extpath = Strnew(); + + if (name == NULL) + return NULL; + p = name; + if (*p == '~') { + p++; + if (IS_ALPHA(*p)) { + userName = Strnew(); + while (IS_ALNUM(*p) || *p == '_' || *p == '-') + Strcat_char(userName, *(p++)); + passent = getpwnam(userName->ptr); + if (passent == NULL) { + p = name; + goto rest; + } + Strcat_charp(extpath, passent->pw_dir); + } + else { + Strcat_charp(extpath, getenv("HOME")); + } + if (Strcmp_charp(extpath, "/") == 0 && *p == '/') + p++; + } + rest: + Strcat_charp(extpath, p); + return extpath->ptr; +} + +Str +escape_shellchar(Str s) +{ + Str x = Strnew(); + int i; + for (i = 0; i < s->length; i++) { + switch (s->ptr[i]) { + case ';': + case '&': + case '|': + case '$': + case '!': + case '(': + case ')': + case '{': + case '}': + case '*': + case '?': + Strcat_char(x, '\\'); + /* continue to the next */ + default: + Strcat_char(x, s->ptr[i]); + } + } + return x; +} + +int +non_null(char *s) +{ + if (s == NULL) + return FALSE; + while (*s) { + if (!IS_SPACE(*s)) + return TRUE; + s++; + } + return FALSE; +} + +void +cleanup_line(Str s, int mode) +{ + if (s->length >= 2 && + s->ptr[s->length - 2] == '\r' && + s->ptr[s->length - 1] == '\n') { + Strshrink(s, 2); + Strcat_char(s, '\n'); + } + else if (Strlastchar(s) == '\r') + s->ptr[s->length - 1] = '\n'; + else if (Strlastchar(s) != '\n') + Strcat_char(s, '\n'); + if (mode != PAGER_MODE) { + int i; + for (i = 0; i < s->length; i++) { + if (s->ptr[i] == '\0') + s->ptr[i] = ' '; + } + } +} + +/* Local Variables: */ +/* c-basic-offset: 4 */ +/* tab-width: 8 */ +/* End: */ |