void rmchan(CHANNEL *chan, acetables *g_ape) { if (chan->head != NULL) { struct userslist *head = chan->head; chan->flags |= CHANNEL_NONINTERACTIVE; /* Force to be non interactive (don't send LEFT raw) */ chan->flags &= ~CHANNEL_AUTODESTROY; /* Don't destroy it */ while(head != NULL) { struct userslist *thead = head->next; left(head->userinfo, chan, g_ape); head = thead; } } FIRE_EVENT_NULL(rmchan, chan, g_ape); rmallban(chan); hashtbl_erase(g_ape->hLusers, chan->name); clear_properties(&chan->properties); destroy_pipe(chan->pipe, g_ape); free(chan); chan = NULL; }
void deluser(USERS *user, acetables *g_ape) { if (user == NULL) { return; } FIRE_EVENT_NULL(deluser, user, user->istmp, g_ape); left_all(user, g_ape); char *uin = GET_UIN_FROM_USER(user); /* kill all users connections */ clear_subusers(user, g_ape); hashtbl_erase(g_ape->hSessid, user->sessid); if (uin != NULL && GET_USER_TBL(g_ape) != NULL) { hashtbl_erase(GET_USER_TBL(g_ape), uin); } if (uin != NULL && GET_ONLINE_TBL(g_ape) != NULL) { hashtbl_erase(GET_ONLINE_TBL(g_ape), uin); } if (user->istmp == 0) g_ape->nConnected--; if (user->prev == NULL) { g_ape->uHead = user->next; } else { user->prev->next = user->next; } if (user->next != NULL) { user->next->prev = user->prev; } clear_sessions(user); clear_properties(&user->properties); destroy_pipe(user->pipe, g_ape); HOOK_EVENT(deluser, user, g_ape); /* TODO Add Event */ free(user); }
void rmchan(CHANNEL *chan, acetables *g_ape) { if (chan->head != NULL) { return; } rmallban(chan); hashtbl_erase(g_ape->hLusers, chan->name); clear_properties(&chan->properties); destroy_pipe(chan->pipe, g_ape); free(chan); chan = NULL; }
void deluser(USERS *user, acetables *g_ape) { if (user == NULL) { return; } FIRE_EVENT_NULL(deluser, user, g_ape); left_all(user, g_ape); /* kill all users connections */ clear_subusers(user); hashtbl_erase(g_ape->hSessid, user->sessid); g_ape->nConnected--; if (user->prev == NULL) { g_ape->uHead = user->next; } else { user->prev->next = user->next; } if (user->next != NULL) { user->next->prev = user->prev; } clear_sessions(user); clear_properties(&user->properties); destroy_pipe(user->pipe, g_ape); free(user); user = NULL; }
// proxy->to must be clean void proxy_shutdown(ape_proxy *proxy, acetables *g_ape) { if (proxy->state == PROXY_CONNECTED) { shutdown(proxy->sock.fd, 2); proxy->state = PROXY_TOFREE; } if (proxy->prev != NULL) { proxy->prev->next = proxy->next; } else { g_ape->proxy.list = proxy->next; } if (proxy->next != NULL) { proxy->next->prev = proxy->prev; } destroy_pipe(proxy->pipe, g_ape); if (proxy->state != PROXY_TOFREE) { free(proxy); } }
// TODO: Tab Completion für builtins static char *my_fgets(char *s, int size, int stream) { pipe_set_flag(STDIN_FILENO, F_ECHO, 0); int cc = 0, i = 0; memset(s, 0, size); size--; while ((i < size) && (cc != '\n')) { fflush(stdout); stream_recv(stream, &cc, 1, O_BLOCKING); if (cc == '\t') { const char *last_space = strrchr(s, ' '); bool complete_cmd = (last_space == NULL); if (complete_cmd) last_space = s; else last_space++; char *path = getenv("PATH"); char dirn[strlen(last_space) + strlen(path) + 2]; char curpart[strlen(last_space) + 1]; char ggt[1024]; ggt[0] = 0; int got_count = 0; char duped_path[strlen(path) + 1]; strcpy(duped_path, path); bool complete_from_path = (complete_cmd && (strchr(last_space, '/') == NULL)); char *path_tok_base = duped_path; char *all_fitting = NULL; size_t all_fitting_sz = 0; bool is_dir = false, is_file = false; do { if (!complete_from_path) strcpy(dirn, last_space); else { char *tok = strtok(path_tok_base, ":"); path_tok_base = NULL; if (tok == NULL) break; sprintf(dirn, "%s/%s", tok, last_space); } char *last_slash = strrchr(dirn, '/'); if (last_slash != NULL) { strcpy(curpart, last_slash + 1); last_slash[1] = 0; } else { if (dirn[0] == '(') continue; strcpy(curpart, dirn); strcpy(dirn, "."); } int dir = create_pipe(dirn, O_RDONLY); if (dir < 0) continue; char buf[pipe_get_flag(dir, F_PRESSURE)]; stream_recv(dir, buf, sizeof(buf), 0); destroy_pipe(dir, 0); size_t j = 0; size_t this_len = strlen(curpart); while (buf[j] && (j < sizeof(buf))) { if (!strncmp(buf + j, curpart, this_len)) { size_t all_fitting_off = all_fitting_sz; all_fitting_sz += strlen(buf + j) + 1; all_fitting = realloc(all_fitting, all_fitting_sz); strcpy(all_fitting + all_fitting_off, buf + j); char full_name[strlen(dirn) + 1 + strlen(buf + j) + 1]; sprintf(full_name, "%s/%s", dirn, buf + j); int fd = create_pipe(full_name, O_JUST_STAT); if (fd >= 0) { if (pipe_implements(fd, I_STATABLE)) { if (S_ISDIR(pipe_get_flag(fd, F_MODE))) is_dir = true; else is_file = true; } else is_dir = is_file = true; destroy_pipe(fd, 0); } else is_dir = is_file = true; if (!got_count++) strcpy(ggt, buf + j + this_len); else { size_t k = 0; do { if (ggt[k] != buf[j + this_len + k]) { ggt[k] = 0; break; } } while (ggt[k++]); } } j += strlen(buf + j) + 1; } } while (complete_from_path); if (ggt[0]) { for (size_t k = 0; ggt[k] && (i < size); k++) { putchar(ggt[k]); s[i++] = ggt[k]; } } if (got_count < 2) { if (is_dir ^ is_file) { char chr = is_dir ? '/' : ' '; if (i < size) { putchar(chr); s[i++] = chr; } } } if ((got_count < 2) || ggt[0]) continue; int j = 0; putchar('\n'); while (j < (int)all_fitting_sz) { printf("%s ", all_fitting + j); j += strlen(all_fitting + j) + 1; } printf("\n%s$ %s", getenv("PWD"), s); free(all_fitting); continue; } else if (cc != '\b') putchar(cc); else { if (i) { printf("\b \b"); while (((s[--i] & 0xC0) == 0x80) && (i > 1)) s[i] = 0; s[i] = 0; } continue; } if (cc != '\n') s[i++] = cc; } pipe_set_flag(STDIN_FILENO, F_ECHO, 1); return s; }
void _vfs_deinit(void) { for (int i = 0; i < __MFILE; i++) destroy_pipe(i, 0); }
int main(int argc, char *argv[]) { const char *domain = NULL; const char *dns_ip = NULL; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { fprintf(stderr, "%s: Unknown option '%c'.\n", argv[0], argv[i][0]); return 1; } else { if (argv[i][0] == '@') { if (dns_ip != NULL) { fprintf(stderr, "%s: More than one DNS IP address specified.\n", argv[0]); return 1; } dns_ip = &argv[i][1]; } else if (domain == NULL) domain = argv[i]; else { fprintf(stderr, "%s: Unexpected argument \"%s\".\n", argv[0], argv[i]); return 1; } } } if (domain == NULL) { fprintf(stderr, "%s: Lookup name required.\n", argv[0]); return 1; } uint_fast32_t dns_nip = 0; if (dns_ip != NULL) { char *end = (char *)dns_ip; int ipa[4]; for (int i = 0; i < 4; i++) { ipa[i] = strtol(end, &end, 10); if (ipa[i] & ~0xFF) { fprintf(stderr, "%s: \"%s\" is no valid IP address.\n", argv[0], dns_ip); return 1; } if (((i < 3) && (*end != '.')) || ((i == 3) && *end)) { fprintf(stderr, "%s: \"%s\" is no valid IP address.\n", argv[0], dns_ip); return 1; } dns_nip |= ipa[i] << ((3 - i) * 8); end++; } } char *fname; asprintf(&fname, "(dns)/%s", domain); int fd = create_pipe(fname, O_RDONLY); if (fd < 0) { fprintf(stderr, "%s: Could not open %s: %s\n", argv[0], fname, strerror(errno)); return 1; } free(fname); if (dns_ip != NULL) if (pipe_set_flag(fd, F_DNS_NSIP, dns_nip) < 0) fprintf(stderr, "%s: Error setting namserver IP %s, continuing anyway.\n", argv[0], dns_ip); size_t len = pipe_get_flag(fd, F_PRESSURE); if (!len) { destroy_pipe(fd, 0); fprintf(stderr, "%s: Could not receive IP address.\n", argv[0]); return 1; } char ip[len + 1]; memset(ip, 0, len + 1); stream_recv(fd, ip, len, O_BLOCKING); printf("IP address: %s\n", ip); destroy_pipe(fd, 0); return 0; }