osc7: initial patch implementation (#154)
* osc7: initial patch implementation Closes #153 * osc7: avoid redundant use of realpath() * osc7: fix styling * Changing position of the OSC7_PATCH toggle in patches.def.h --------- Co-authored-by: Bakkeby <bakkeby@gmail.com>
This commit is contained in:
parent
3f1a5ed034
commit
c4c5113fbd
9 changed files with 136 additions and 11 deletions
74
patch/osc7.c
Normal file
74
patch/osc7.c
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
static int
|
||||
hex2int(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
osc7parsecwd(const char *uri)
|
||||
{
|
||||
const char *auth, *host, *hostend;
|
||||
char *path, decoded[PATH_MAX], thishost[_POSIX_HOST_NAME_MAX];
|
||||
size_t i, decodedlen, hostlen, urilen;
|
||||
int h1, h2;
|
||||
if (!term.cwd) {
|
||||
term.cwd = xmalloc(sizeof(decoded));
|
||||
term.cwd[0] = '\0';
|
||||
}
|
||||
/* reset cwd if uri is empty */
|
||||
if ((urilen = strlen(uri)) == 0) {
|
||||
term.cwd[0] = '\0';
|
||||
return 1;
|
||||
}
|
||||
/* decode uri */
|
||||
for (decodedlen = 0, i = 0; i < urilen; i++) {
|
||||
if (uri[i] == '%' && i <= urilen-3 &&
|
||||
(h1 = hex2int(uri[i+1])) >= 0 && (h2 = hex2int(uri[i+2])) >= 0) {
|
||||
decoded[decodedlen++] = (h1 << 4) | h2;
|
||||
i += 2;
|
||||
} else {
|
||||
decoded[decodedlen++] = uri[i];
|
||||
}
|
||||
if (decodedlen == sizeof(decoded)) {
|
||||
fprintf(stderr, "erresc (OSC 7): uri is too long\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
decoded[decodedlen] = '\0';
|
||||
/* check scheme */
|
||||
if (decodedlen < 5 || strncmp("file:", decoded, 5) != 0) {
|
||||
fprintf(stderr, "erresc (OSC 7): scheme is not supported: '%s'\n", uri);
|
||||
return 0;
|
||||
}
|
||||
/* find start of authority */
|
||||
if (decodedlen < 7 || decoded[5] != '/' || decoded[6] != '/') {
|
||||
fprintf(stderr, "erresc (OSC 7): invalid uri: '%s'\n", uri);
|
||||
return 0;
|
||||
}
|
||||
auth = decoded + 7;
|
||||
/* find start of path and reset cwd if path is missing */
|
||||
if ((path = strchr(auth, '/')) == NULL) {
|
||||
term.cwd[0] = '\0';
|
||||
return 1;
|
||||
}
|
||||
/* ignore path if host is not localhost */
|
||||
host = ((host = memchr(auth, '@', path - auth)) != NULL) ? host+1 : auth;
|
||||
hostend = ((hostend = memchr(host, ':', path - host)) != NULL) ? hostend : path;
|
||||
hostlen = hostend - host;
|
||||
if (gethostname(thishost, sizeof(thishost)) < 0)
|
||||
thishost[0] = '\0';
|
||||
if (hostlen > 0 &&
|
||||
!(hostlen == 9 && strncmp("localhost", host, hostlen) == 0) &&
|
||||
!(hostlen == strlen(thishost) && strncmp(host, thishost, hostlen) == 0)) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(term.cwd, path, decodedlen - (path - decoded) + 1);
|
||||
return 1;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue