summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Ball <nullspoon@oper.io>2020-12-29 21:29:37 -0700
committerAaron Ball <nullspoon@oper.io>2020-12-29 21:29:37 -0700
commit27e5f085e0aaf873c545344f7556a841b5e37f69 (patch)
tree532401f86c88a6fdca4f4ea0f102bdecb9f8fd56
parent1e223470ee80c794f2330e5a80145fd5a0dfb504 (diff)
parentc407d6fa52aa5e579dd7e42e0b161111a8e31032 (diff)
downloadoper.io-27e5f085e0aaf873c545344f7556a841b5e37f69.tar.gz
oper.io-27e5f085e0aaf873c545344f7556a841b5e37f69.tar.xz
Merge branch 'implement-runsh'
-rw-r--r--posts/librem5-no-wifi.rst8
-rw-r--r--src/common.c20
-rw-r--r--src/common.h3
-rw-r--r--src/j2.c100
-rw-r--r--src/j2.h5
-rw-r--r--src/main.c2
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
diff --git a/src/j2.c b/src/j2.c
index 05fe442..b636c77 100644
--- a/src/j2.c
+++ b/src/j2.c
@@ -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);
diff --git a/src/j2.h b/src/j2.h
index 3e958d3..c08f9ec 100644
--- a/src/j2.h
+++ b/src/j2.h
@@ -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
diff --git a/src/main.c b/src/main.c
index 0e608f6..297ea96 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);

Generated by cgit