added session manager and support for an external login system
[TransparentIRC.git] / src / tools.c
index 6478279f7aa2dc0ce5bfa392129c2faed42d3723..5a26b192382c690d35260e723cd31839faf22c25 100644 (file)
@@ -39,4 +39,102 @@ int stricmplen(const char *s1, const char *s2, int len) {
         if(i == len) break;
     }
     return c1 - c2;
-}
\ No newline at end of file
+}
+
+int parse_line(char *line, char **argv, int irc_raw) {
+    int argc = 0;
+    if(irc_raw) {
+        if(line[0] == ':')
+            line++;
+        else
+            argv[argc++] = NULL;
+    }
+    while(*line) {
+        //skip leading spaces
+        while (*line == ' ')
+            *line++ = 0;
+        if (*line == ':' && irc_raw) {
+           //the rest is a single parameter
+           argv[argc++] = line + 1;
+           break;
+        }
+        argv[argc++] = line;
+        if (argc >= MAXNUMPARAMS)
+            break;
+        while (*line != ' ' && *line)
+            line++;
+    }
+    return argc;
+}
+
+void build_var_string(char *buffer, char *format, struct variable_replace_map *map) {
+    int bufferpos = 0;
+    int i, escape = 0;
+    char *p = format;
+    char *tmp;
+    while(*p) {
+        if(escape) {
+            escape = 0;
+            goto build_var_string_addchar;
+        }
+        if(*p == '\\') {
+            escape = 1;
+            p++;
+            continue;
+        }
+        if(*p == '%') {
+            p++;
+            for(i = 0; ; i++) {
+                if(!map[i].character) {
+                    tmp = NULL;
+                    break;
+                }
+                if(map[i].character == *p) {
+                    tmp = map[i].value;
+                    break;
+                }
+            }
+            if(!tmp) {
+                p--;
+                goto build_var_string_addchar;
+            }
+            for(i = 0; tmp[i] && bufferpos < CMDLEN; i++) {
+                buffer[bufferpos++] = tmp[i]; 
+            }
+        } else {
+            build_var_string_addchar:
+            buffer[bufferpos++] = *p;
+            if(bufferpos == CMDLEN)
+                break;
+        }
+        p++;
+    }
+    buffer[bufferpos++] = '\0';
+}
+
+int run_external_process(char *command, char **parameters) { //win32 incompatible
+    int sockets[2], child;
+    if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0)
+        return -1;
+    if ((child = fork()) == -1) {
+        close(sockets[0]);
+        close(sockets[1]);
+        return -1;
+    }
+    else if (child) { // This is the parent.
+        close(sockets[0]);
+        wait(NULL);
+        return sockets[1];
+    } else { // This is the child.
+        close(sockets[1]);
+        child = fork(); //double fork to prevent zombies
+        if(child < 0) exit(EXIT_FAILURE);
+        if(child != 0) exit(EXIT_SUCCESS);
+        if(dup2(sockets[0], 1) != -1) {
+            execvp(command, parameters);
+        }
+        close(sockets[0]);
+        exit(EXIT_FAILURE);
+    }
+}
+