diff options
author | Aaron Ball <nullspoon@oper.io> | 2020-12-29 21:29:37 -0700 |
---|---|---|
committer | Aaron Ball <nullspoon@oper.io> | 2020-12-29 21:29:37 -0700 |
commit | 27e5f085e0aaf873c545344f7556a841b5e37f69 (patch) | |
tree | 532401f86c88a6fdca4f4ea0f102bdecb9f8fd56 | |
parent | 1e223470ee80c794f2330e5a80145fd5a0dfb504 (diff) | |
parent | c407d6fa52aa5e579dd7e42e0b161111a8e31032 (diff) | |
download | oper.io-27e5f085e0aaf873c545344f7556a841b5e37f69.tar.gz oper.io-27e5f085e0aaf873c545344f7556a841b5e37f69.tar.xz |
Merge branch 'implement-runsh'
-rw-r--r-- | posts/librem5-no-wifi.rst | 8 | ||||
-rw-r--r-- | src/common.c | 20 | ||||
-rw-r--r-- | src/common.h | 3 | ||||
-rw-r--r-- | src/j2.c | 100 | ||||
-rw-r--r-- | src/j2.h | 5 | ||||
-rw-r--r-- | src/main.c | 2 |
6 files changed, 101 insertions, 37 deletions
diff --git a/posts/librem5-no-wifi.rst b/posts/librem5-no-wifi.rst index 2803404..bba7cbf 100644 --- a/posts/librem5-no-wifi.rst +++ b/posts/librem5-no-wifi.rst @@ -22,10 +22,12 @@ the phone with a SIM card, it would have retrieved the time from the cell network or perhaps NTP and it would not have been an issue. However, I booted it with no SIM card plugged in, so it had no way to know the date. -To fix this, you can copy pasta this command in the terminal, replacing the -date provided here with the actual date and time:: +To fix this, you can copy pasta this command in the terminal. It is updated on +page load, so it should work as-is. - sudo date -s "2020-12-27 12:00" +.. code-block:: sh + + sudo date -s "{{ shell date '+%F %T %Z' }}" You don't need to get that accurate to the second, or even the minute or hour to make things work. The NTP service should be able to adjust it slowly in the diff --git a/src/common.c b/src/common.c index 1891d78..db33bc0 100644 --- a/src/common.c +++ b/src/common.c @@ -75,3 +75,23 @@ int html_read_title(char* path, char* out) { return -1; } + +char* runsh(char* cmd) { + char buf[2048] = {'\0'}; + char* out = malloc(1); + FILE* fd = NULL; + unsigned long len = 0; + + fd = popen(cmd, "r"); + while(fgets(buf, 2048, fd) != NULL) { + len += strlen(buf); + out = realloc(out, len + 1); + strcat(out, buf); + } + pclose(fd); + + if(out[len - 1] == '\n') + out[len-1] = '\0'; + return out; +} + diff --git a/src/common.h b/src/common.h index aca549d..03529dd 100644 --- a/src/common.h +++ b/src/common.h @@ -16,6 +16,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <stdio.h> +#include <stdlib.h> #include <string.h> #ifndef _common_h @@ -29,4 +30,6 @@ int file_exists(char*); int html_read_title(char*, char*); +char* runsh(char*); + #endif @@ -18,30 +18,47 @@ #include "j2.h" -int j2_readvar(FILE* fd, char* buf) { - char c; - int i = 0; - fpos_t startpos; +char* j2_strstr(char* line) { + char* start; + char* end; - fgetpos(fd, &startpos); - //long seekstart = SEEK_CUR; + start = strstr(line, "{{ "); + if(start == NULL) + return NULL; + //start += 3; // Advance past the '{{ ' - if((c = fgetc(fd)) != '{') { - fsetpos(fd, &startpos); - return -1; - } - if(fgetc(fd) != ' ') { - fsetpos(fd, &startpos); - return -1; - } + // Check for the var close to ensure a complete definition is present + end = strstr(start, " }}"); - while((c = fgetc(fd)) != ' ') { - buf[i] = c; - i++; - } + // Incorrectly formatted, early return null + if(end == NULL) + return NULL; + + return start; +} + + +char* j2_readvar(char* line, char* buf, int maxlen) { + char* start = NULL; + char* end = NULL; - buf[i] = '\0'; - return 1; + start = j2_strstr(line); + if(start == NULL) + return NULL; + start += 3; + + // Because of how j2_strstr works, this will always work if start is not null + end = strstr(start, " }}"); + + // Only copy up to maxlen to avoid buffer overflows + if(end - start > maxlen) { + strncpy(buf, start, maxlen); + buf[maxlen] = '\0'; + } else { + strncpy(buf, start, end - start); + buf[end - start] = '\0'; + } + return end + 3; } @@ -50,23 +67,42 @@ int j2_readvar(FILE* fd, char* buf) { * matching environment variables. */ int j2_cat(char* path) { - char buf[512] = {'\0'}; - char c; + char line[J2_MAXLINE] = {'\0'}; + char buf[J2_MAXBUF] = {'\0'}; FILE* fd = fopen(path, "r"); + char* value = NULL; + char* varstart = NULL; + char* varend = NULL; - while((c = fgetc(fd)) != EOF) { - if(c == '{') { - if(j2_readvar(fd, buf) == -1) { - printf("{%s", buf); - continue; - } + while(fgets(line, J2_MAXLINE, fd) != NULL) { + varstart = j2_strstr(line); - printf("%s", getenv(buf)); - fgetc(fd); - fgetc(fd); + if(!varstart) { + printf(line); continue; } - printf("%c", c); + varend = j2_readvar(varstart, buf, J2_MAXBUF); + + // Break the beginning of the string and the beginning of the variable + // (this overwrites the first { that opens the variable def) + *varstart = '\0'; + // Because of the inserted null byte, this will print from byte 0 to there + printf("%s", line); + + // Execute the variable directive and print the output + if(strncmp(buf, "shell ", 6) == 0) { + // Execute the provided shell command and print that + value = runsh(&buf[6]); + printf("%s", value); + free(value); + } else { + // Print the referenced environment variable + value = getenv(buf); + printf("%s", value); + } + + // varend points to after the final }} of the variable def + printf("%s", varend); } fclose(fd); @@ -18,9 +18,12 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include "common.h" -int j2_readvar(FILE*, char*); +#define J2_MAXLINE 4096 +#define J2_MAXBUF 1024 +char* j2_readvar(char*, char*, int); /** * Reads a jinja file and cats the output, interpolating variables, values from @@ -83,7 +83,7 @@ int main(int argc, char* argv[], char* envp[]) { setenv("PAGE_TITLE", title, 1); j2_cat(header); - catfile(path); + j2_cat(path); j2_cat(footer); fflush(stdout); |