binresult *get_result(apisock *sock){ unsigned char *data; binresult *res; uint32_t ressize; if (readall(sock, &ressize, sizeof(uint32_t))!=sizeof(uint32_t)) return NULL; data=(unsigned char *)malloc(ressize); if (readall(sock, data, ressize)!=ressize){ free(data); return NULL; } res=parse_result(data, ressize); free(data); return res; }
/* * encrypt a file using symmetric cryptography (a password) */ static void symencrypt(const char *msgfile, const char *encfile, int rounds) { struct symmsg symmsg; uint8_t symkey[SYMKEYBYTES]; uint8_t *msg; unsigned long long msglen; kdf_allowstdin allowstdin = { strcmp(msgfile, "-") != 0 }; kdf_confirm confirm = { 1 }; msg = readall(msgfile, &msglen); memcpy(symmsg.kdfalg, KDFALG, 2); memcpy(symmsg.symalg, SYMALG, 2); symmsg.kdfrounds = htonl(rounds); randombytes(symmsg.salt, sizeof(symmsg.salt)); kdf(symmsg.salt, sizeof(symmsg.salt), rounds, allowstdin, confirm, symkey, sizeof(symkey)); symencryptmsg(msg, msglen, symmsg.box, symkey); explicit_bzero(symkey, sizeof(symkey)); writeencfile(encfile, &symmsg, sizeof(symmsg), "<symmetric>", msg, msglen); xfree(msg, msglen); }
static void skipfile(int fd, size_t size) { ssize_t rc; size_t ar; char array[512]; ar = 0; while(ar != size) { rc = readall(fd, array, (size-ar < 512 ? size - ar : 512)); if(rc < 0) { printf("readmtcp skipfile: error %d skipping checkpoint\n", errno); exit(1); } else if(rc == 0) { printf("readmtcp skipfile: only skipped %zu bytes instead of %zu from" " checkpoint file\n", ar, size); exit(1); } ar += rc; } }
/* * encrypt a file using public key cryptography * authenticated secret key version */ static void pubencrypt(const char *pubkeyfile, const char *ident, const char *seckeyfile, const char *msgfile, const char *encfile) { char myident[IDENTLEN]; struct encmsg encmsg; struct pubkey pubkey; struct seckey seckey; uint8_t *msg; unsigned long long msglen; kdf_allowstdin allowstdin = { strcmp(msgfile, "-") != 0 }; getpubkey(pubkeyfile, ident, &pubkey); getseckey(seckeyfile, &seckey, myident, allowstdin); msg = readall(msgfile, &msglen); memcpy(encmsg.encalg, ENCALG, 2); memcpy(encmsg.pubfingerprint, pubkey.fingerprint, FPLEN); memcpy(encmsg.secfingerprint, seckey.fingerprint, FPLEN); pubencryptmsg(msg, msglen, encmsg.box, pubkey.enckey, seckey.enckey); explicit_bzero(&seckey, sizeof(seckey)); writeencfile(encfile, &encmsg, sizeof(encmsg), myident, msg, msglen); xfree(msg, msglen); }
static int login_readwelcome(struct clientinfo *clntinfo) { /* Read the welcome line */ clntinfo->login.welcomemsg = readall(clntinfo->serversocket); if (!clntinfo->login.welcomemsg.fullmsg) { /* an error occurred */ if (timeout) { jlog(2, "Timeout in %s line %d\n", __FILE__ ,__LINE__); err_time_readline(clntinfo->clientsocket); } else { set_errstr("Server closed the connection"); err_readline(clntinfo->clientsocket); } return CMD_ABORT; } jlog(9, "Connected to %s, got \"%s\" as welcome message", clntinfo->destination, clntinfo->login.welcomemsg.fullmsg); if (!checkbegin(clntinfo->login.welcomemsg.lastmsg, "220 ")) { jlog(2, "Not a valid FTP server response (%s)", clntinfo->login.welcomemsg.fullmsg); say(clntinfo->clientsocket,clntinfo->login.welcomemsg.fullmsg); free(clntinfo->login.welcomemsg.fullmsg); clntinfo->login.welcomemsg.fullmsg = (char*) 0; clntinfo->login.welcomemsg.lastmsg = (char*) 0; return CMD_ERROR; } return CMD_HANDLED; }
/* * main sign function */ static void sign(const char *seckeyfile, const char *msgfile, const char *sigfile, int embedded) { struct sig sig; struct seckey seckey; char ident[IDENTLEN]; uint8_t *msg; unsigned long long msglen; kdf_allowstdin allowstdin = { strcmp(msgfile, "-") != 0 }; getseckey(seckeyfile, &seckey, ident, allowstdin); msg = readall(msgfile, &msglen); signmsg(seckey.sigkey, msg, msglen, sig.sig); memcpy(sig.fingerprint, seckey.fingerprint, FPLEN); memcpy(sig.sigalg, SIGALG, 2); explicit_bzero(&seckey, sizeof(seckey)); if (embedded) writesignedmsg(sigfile, &sig, ident, msg, msglen); else writekeyfile(sigfile, "SIGNATURE", &sig, sizeof(sig), ident, O_TRUNC, 0666); free(msg); }
void parse_region (int fd, UINT size) { struct region region; readall (fd, ®ion, sizeof(region)); region_count++; app_record_count++; if (options.print) { printf ("Region Record %d:\n", region_count); printf (" ID: %d (0x%04x)\n", region.id, region.id); printf (" Delay: %u\n", region.delay); printf (" Size: "); if (options.human_readable) print_human_readable (region.size); else printf("%u", region.size); printf("\n"); } if (options.extract == region_count) { fd_copy (1, fd, region.size); options.extract = -1; } else { lseek (fd, region.size, SEEK_CUR); } }
int main() { bytes_result r = readall(); if (!r.ok) { fprintf(stderr, "readall failed\n"); exit(1); } r = split(r.data, '\n'); if (!r.ok) { fprintf(stderr, "split failed.\n"); exit(1); } bytes lines = r.data; quicksort((slice*)lines.ptr, 0, (lines.len/sizeof(slice))-1); for(int i = 0; i < lines.len; i += sizeof(slice)) { slice* s = (slice*)(lines.ptr + i); int rc = fwrite(s->ptr, 1, s->len, stdout); if (rc != s->len) { fprintf(stderr, "Error writing to stdout.\n"); exit(1); } putchar('\n'); } return 0; }
/* * encrypt a file using public key cryptography * ephemeral key version that discards sender key pair */ static void ekpubencrypt(const char *pubkeyfile, const char *ident, const char *msgfile, const char *encfile) { struct ekcmsg ekcmsg; struct pubkey pubkey; uint8_t *msg; unsigned long long msglen; uint8_t enckey[ENCSECRETBYTES]; getpubkey(pubkeyfile, ident, &pubkey); crypto_box_keypair(ekcmsg.pubkey, enckey); msg = readall(msgfile, &msglen); memcpy(ekcmsg.ekcalg, EKCALG, 2); memcpy(ekcmsg.pubfingerprint, pubkey.fingerprint, FPLEN); pubencryptmsg(msg, msglen, ekcmsg.box, pubkey.enckey, enckey); explicit_bzero(&enckey, sizeof(enckey)); writeencfile(encfile, &ekcmsg, sizeof(ekcmsg), "<ephemeral>", msg, msglen); xfree(msg, msglen); }
static int read_header(struct crypt_device *cd, int flags, uint32_t *length, lm_t *lm) { uint32_t maxlen; int fd = -1; int r = 0; fd = open_hole(cd, flags, length); if (fd < 0) return fd; r = *length >= sizeof(lm_t) ? 0 : -ENOENT; if (r < 0) goto error; r = readall(fd, lm, sizeof(lm_t)); if (r < 0) goto error; r = memcmp(LM_MAGIC, lm->magic, sizeof(LM_MAGIC)) == 0 ? 0 : -ENOENT; if (r < 0) goto error; r = lm->version == htobe32(LM_VERSION) ? 0 : -ENOTSUP; if (r < 0) goto error; lm->crc32c = be32toh(lm->crc32c); r = checksum(*lm) == lm->crc32c ? 0 : -EINVAL; if (r < 0) goto error; lm->version = be32toh(lm->version); maxlen = *length - ALIGN(sizeof(lm_t), true); for (int slot = 0; slot < LUKS_NSLOTS; slot++) { lm_slot_t *s = &lm->slots[slot]; s->offset = be32toh(s->offset); s->length = be32toh(s->length); s->crc32c = be32toh(s->crc32c); if (!uuid_is_zero(s->uuid)) { r = s->offset > sizeof(lm_t) ? 0 : -EINVAL; if (r < 0) goto error; r = s->length <= maxlen ? 0 : -EINVAL; if (r < 0) goto error; } } return fd; error: close(fd); return r; }
static ssize_t get(struct store *st, void *buf, size_t len, struct addr *at) { idx_t i; struct idxent ie; struct fstore *fst; struct logent le; struct addr v; char tmpbuf[STORE_MAXBLSZ]; fst = st->pdata; if((i = lookup(fst, at, NULL)) == -1) { errno = ENOENT; return(-1); } assert(!getidx(fst, i, &ie)); if(readall(fst->logfd, &le, sizeof(le), ie.off)) { flog(LOG_CRIT, "could not read log entry: %s", strerror(errno)); errno = EIO; return(-1); } if(memcmp(le.magic, LOGENTMAGIC, 4)) { flog(LOG_CRIT, "invalid magic in log"); errno = EIO; return(-1); } if(addrcmp(&le.name, at)) { flog(LOG_CRIT, "did not receive correct block from log"); errno = EIO; return(-1); } if(readall(fst->logfd, tmpbuf, le.len, ie.off + sizeof(le))) { flog(LOG_CRIT, "could not read log data: %s", strerror(errno)); errno = EIO; return(-1); } hash(tmpbuf, le.len, &v); if(addrcmp(&v, &le.name)) { flog(LOG_CRIT, "log data did not verify against hash"); errno = EIO; return(-1); } if(buf != NULL) memcpy(buf, tmpbuf, min(len, le.len)); return(le.len); }
int load(const char *fn,void *x,long long xlen) { int fd; int r; fd = open_read(fn); if (fd == -1) return -1; r = readall(fd,x,xlen); close(fd); return r; }
static void readcs (int fd, char cs) { char xcs; readall(fd, &xcs, sizeof xcs); if (xcs != cs) { fprintf (stderr, "readmtcp readcs: checkpoint section %d next, expected %d\n", xcs, cs); abort (); } }
int main() { printf("Hello boys!\n"); createfile(); readtxt(); readall(); return 0; }
int luksmeta_load(struct crypt_device *cd, int slot, luksmeta_uuid_t uuid, void *buf, size_t size) { uint32_t length = 0; lm_slot_t *s = NULL; lm_t lm = {}; int fd = -1; int r = 0; if (slot < 0 || slot >= LUKS_NSLOTS) return -EBADSLT; s = &lm.slots[slot]; fd = read_header(cd, O_RDONLY, &length, &lm); if (fd < 0) return fd; r = uuid_is_zero(s->uuid) ? -ENODATA : 0; if (r < 0) goto error; if (buf) { r = size >= s->length ? 0 : -E2BIG; if (r < 0) goto error; r = lseek(fd, s->offset - sizeof(lm), SEEK_CUR) == -1 ? -errno : 0; if (r < 0) goto error; r = readall(fd, buf, s->length); if (r < 0) goto error; r = crc32c(0, buf, s->length) == s->crc32c ? 0 : -EINVAL; if (r < 0) goto error; } memcpy(uuid, s->uuid, sizeof(luksmeta_uuid_t)); close(fd); return s->length; error: close(fd); return r; }
static char* sendMediaproxyCommand(char *command) { struct sockaddr_un addr; int smpSocket, len; static char buf[1024]; memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_LOCAL; strncpy(addr.sun_path, mediaproxySocket, sizeof(addr.sun_path) - 1); #ifdef HAVE_SOCKADDR_SA_LEN addr.sun_len = strlen(addr.sun_path); #endif smpSocket = socket(AF_LOCAL, SOCK_STREAM, 0); if (smpSocket < 0) { LOG(L_ERR, "error: mediaproxy/sendMediaproxyCommand(): can't create socket\n"); return NULL; } if (connect(smpSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) { close(smpSocket); LOG(L_ERR, "error: mediaproxy/sendMediaproxyCommand(): can't connect to MediaProxy\n"); return NULL; } len = uwrite(smpSocket, command, strlen(command)); if (len <= 0) { close(smpSocket); LOG(L_ERR, "error: mediaproxy/sendMediaproxyCommand(): can't send command to MediaProxy\n"); return NULL; } len = readall(smpSocket, buf, sizeof(buf)-1); close(smpSocket); if (len < 0) { LOG(L_ERR, "error: mediaproxy/sendMediaproxyCommand(): can't read reply from MediaProxy\n"); return NULL; } buf[len] = 0; return buf; }
int main(int argc, char *argv[]) { if (geteuid() > 0) { fprintf(stderr, "error: this program requires superuser privilages\n"); return 1; /* exit failure */ } if (argc < 3) { print_usage(); return 1; /* exit failure */ } char *fpath = argv[argc - 2]; char *iface = argv[argc - 1]; int sd = create_rawsock(iface); if (sd == -1) { fprintf(stderr, "error: failure to create network connection\n"); return 1; /* exit failure */ } int fd = open(fpath, O_RDONLY); if (fd == -1) { fprintf(stderr, "error: failure to open file (%s)\n", fpath); return 1; /* exit failure */ } char *buf = NULL; ssize_t rbytes = readall(fd, (void **)&buf); if (rbytes == -1) { fprintf(stderr, "error: failure reading from file\n"); return 1; /* exit failure */ } close(fd); /* no further use for file */ ssize_t wbytes = writeall(sd, buf, rbytes); if (wbytes == -1) { fprintf(stderr, "error: failure writing packet to network\n"); return 1; /* exit failure */ } close(sd); free(buf); return 0; /* exit success */ }
/* * message followed by signature in one file */ static void verifyembedded(const char *pubkeyfile, const char *sigfile, int quiet) { char ident[IDENTLEN]; struct sig sig; struct pubkey pubkey; uint8_t *msg; unsigned long long msglen; uint8_t *msgdata; unsigned long long msgdatalen; char *begin, *end; const char *beginreopmsg = "-----BEGIN REOP SIGNED MESSAGE-----\n"; const char *beginreopsig = "-----BEGIN REOP SIGNATURE-----\n"; const char *endreopmsg = "-----END REOP SIGNED MESSAGE-----\n"; msgdata = readall(sigfile, &msgdatalen); if (strncmp(msgdata, beginreopmsg, strlen(beginreopmsg)) != 0) goto fail; begin = msgdata + 36; if (!(end = strstr(begin, beginreopsig))) goto fail; *end = 0; msg = begin; msglen = end - begin; begin = end + 31; if (!(end = strstr(begin, endreopmsg))) goto fail; *end = 0; begin = readident(begin, ident); if (b64_pton(begin, (void *)&sig, sizeof(sig)) != sizeof(sig)) goto fail; getpubkey(pubkeyfile, ident, &pubkey); verifymsg(&pubkey, msg, msglen, &sig, quiet); free(msgdata); return; fail: errx(1, "invalid signature: %s", sigfile); }
void parse_advr (int fd, UINT size) { struct advr advr; readall (fd, &advr, size); cond_print ("Application Data Version Record:\n"); cond_print (" Version: %u.%02u\n", advr.version / 100, advr.version % 100); advr_count++; app_record_count++; if (app_record_count == 1) first_record_is_advr = 1; else first_record_is_advr = 0; }
void parse_avr (int fd, UINT size) { struct avr avr; char *buf; int pos; /* Strings are of unknown length, so memory for * this record must be dynamic */ buf = xmalloc (size); readall (fd, buf, size); pos = 0; /* Copy version value into struct */ avr.version = *(typeof(avr.version) *)&buf[pos]; pos += sizeof (avr.version); /* Set string pointers in struct to locations in buf */ avr.builder = &buf[pos]; pos += strnlen (avr.builder, size - pos - 1) + 1; avr.build_date = &buf[pos]; pos += strnlen (avr.build_date, size - pos - 1) + 1; avr.build_time = &buf[pos]; pos += strnlen (avr.build_time, size - pos - 1) + 1; if (buf[size - 1] != 0) { buf[size - 1] = 0; valid = 0; } /* print it */ cond_print ("Application Version Record:\n"); cond_print (" Version: %u.%02u\n", avr.version / 100, avr.version % 100); cond_print (" Builder: %s\n", avr.builder); cond_print (" Build date: %s\n", avr.build_date); cond_print (" Build time: %s\n", avr.build_time); free (buf); avr_count++; app_record_count++; }
static void run(void (*op)(void), const char *exp) { pid_t pid; int status, fromchild[2]; long long r, i; if (pipe(fromchild) == -1) fail("pipe() failure"); pid = fork(); if (pid == -1) fail("fork() failure"); if (pid == 0) { close(fromchild[0]); if (dup2(fromchild[1], 2) == -1) _exit(111); op(); _exit(0); } close(fromchild[1]); r = readall(fromchild[0], logbuf, sizeof logbuf); if (r == -1) fail("read() failure"); for (i = 0; i < r; ++i) if (logbuf[i] == '\n') break; r = i; for (i = 0; i < r; ++i) if (logbuf[i] == '/') break; r -= i; byte_copy(logbuf, r, logbuf + i); /* fprintf(stderr, "xxx: %s\n", logbuf); fflush(stderr); */ if (r < globalpathlen + 1) fail("log error"); if (!byte_isequal(globalpath, globalpathlen, logbuf)) fail("log error"); r -= globalpathlen + 1; byte_copy(logbuf, r, logbuf + globalpathlen + 1); for (i = 0; i < r; ++i) if (logbuf[i] == '{') break; r = i; logbuf[r] = 0; while (waitpid(pid, &status, 0) != pid) {}; if (!WIFEXITED(status)) fail("process killed"); if (WEXITSTATUS(status)) fail("process exited with status != 0"); i = str_len(exp); if (r != i) fail("failed"); if (!byte_isequal(logbuf, i, exp)) fail("failed"); }
static idx_t newindex(struct fstore *fst) { size_t newsize; idx_t ni; struct idxent ne; struct idxhdr ih; /* XXX: Thread safety */ ni = fst->idxsize++; newsize = sizeof(struct idxhdr) + fst->idxsize * sizeof(struct idxent); if(ftruncate(fst->idxfd, newsize)) return(-1); ne.l = ne.r = 0; assert(!putidx(fst, ni, &ne)); assert(!readall(fst->idxfd, &ih, sizeof(ih), 0)); ih.size = fst->idxsize; assert(!writeall(fst->idxfd, &ih, sizeof(ih), 0)); return(ni); }
/* * simple case, detached signature */ static void verifysimple(const char *pubkeyfile, const char *msgfile, const char *sigfile, int quiet) { char ident[IDENTLEN]; struct sig sig; struct pubkey pubkey; unsigned long long msglen; uint8_t *msg; msg = readall(msgfile, &msglen); readkeyfile(sigfile, &sig, sizeof(sig), ident); getpubkey(pubkeyfile, ident, &pubkey); verifymsg(&pubkey, msg, msglen, &sig, quiet); free(msg); }
static int login_sendauth_user(struct clientinfo* clntinfo) { size_t sendbufsize, ret; char* sendbuf; if (clntinfo->login.stage >= LOGIN_ST_USER) { return CMD_HANDLED; } sendbufsize = strlen("USER \r\n") + strlen(clntinfo->user) + 1; sendbuf = (char*) malloc(sendbufsize); enough_mem(sendbuf); snprintf(sendbuf, sendbufsize, "USER %s\r\n", clntinfo->user); ret = say(clntinfo->serversocket, sendbuf); free(sendbuf); sendbuf = 0; if (ret < 0) { jlog(2, "Error writing the user name to the server: %s", strerror(errno)); return CMD_ABORT; } clntinfo->login.authresp = readall(clntinfo->serversocket); if (!clntinfo->login.authresp.fullmsg) { if (timeout) { jlog(2, "Timeout in %s line %d\n", __FILE__ ,__LINE__); err_time_readline(clntinfo->clientsocket); } else { err_readline(clntinfo->clientsocket); } free(clntinfo->login.welcomemsg.fullmsg); clntinfo->login.welcomemsg.fullmsg = (char*) 0; clntinfo->login.welcomemsg.lastmsg = (char*) 0; return CMD_ABORT; } clntinfo->login.stage = LOGIN_ST_USER; return CMD_HANDLED; }
size_t readmore(int sock, char *buf, size_t n) { fd_set rfds; int ret, bytes; poll_wait(sock, POLLERR | POLLIN ); bytes = readall(sock, buf, n); if (0 == bytes) { perror("Connection closed"); errx(1, "Readmore Connection closure"); /* NOT REACHED */ } return bytes; }
int parse_vir (int fd) { struct vir vir; readall (fd, &vir, sizeof(vir)); cond_print ("Version Identification Record:\n"); cond_print (" File ID: 0x%08x (\"%c%c%c%c\")\n", vir.file_id, ((char *)&vir.file_id)[3], ((char *)&vir.file_id)[2], ((char *)&vir.file_id)[1], ((char *)&vir.file_id)[0]); cond_print (" Version: %u.%02u\n", vir.version / 100, vir.version % 100); if (vir.file_id != FILE_ID) { cond_print ("Error: VIR file ID is not correct. Should be " stringize(FILE_ID) " (\"KpGr\")\n"); valid = 0; } return 1; }
/* * try to read a few different kinds of files */ static void readkeyfile(const char *filename, void *key, size_t keylen, char *ident) { char *keydata; unsigned long long keydatalen; char *begin, *end; const char *beginreop = "-----BEGIN REOP"; const char *endreop = "-----END REOP"; keydata = readall(filename, &keydatalen); if (strncmp(keydata, beginreop, strlen(beginreop)) != 0 || !(end = strstr(keydata, endreop))) errx(1, "invalid key: %s", filename); *end = 0; if (!(begin = strchr(keydata, '\n'))) errx(1, "invalid key: %s", filename); begin = readident(begin + 1, ident); *end = 0; if (b64_pton(begin, key, keylen) != keylen) errx(1, "invalid b64 encoding: %s", filename); xfree(keydata, keydatalen); }
// skip this many bytes of input. Return 0 for success, >0 means this much // left after input skipped. off_t lskip(int fd, off_t offset) { off_t cur = lseek(fd, 0, SEEK_CUR); if (cur != -1) { off_t end = lseek(fd, 0, SEEK_END) - cur; if (end > 0 && end < offset) return offset - end; end = offset+cur; if (end == lseek(fd, end, SEEK_SET)) return 0; perror_exit("lseek"); } while (offset>0) { size_t try_ = ((size_t)offset > sizeof(libbuf)) ? sizeof(libbuf) : (size_t)offset; int or = readall(fd, libbuf, try_); if (or < 0) perror_exit("lskip to %lld", (long long)offset); else offset -= or; if ((size_t)or < try_) break; } return offset; }
void inotifyd_main(void) { struct pollfd fds; char *prog_args[5], **ss = toys.optargs; char *masklist ="acew0rmyndDM uox"; fds.events = POLLIN; *prog_args = *toys.optargs; prog_args[4] = 0; if ((fds.fd = inotify_init()) == -1) perror_exit(0); // Track number of watched files. First one was program to run. toys.optc--; while (*++ss) { char *path = *ss, *masks = strchr(*ss, ':'); int i, mask = 0; if (!masks) mask = 0xfff; // default to all else{ *masks++ = 0; for (*masks++ = 0; *masks; masks++) { i = stridx(masklist, *masks);; if (i == -1) error_exit("bad mask '%c'", *masks); mask |= 1<<i; } } // This returns increasing numbers starting from 1, which coincidentally // is the toys.optargs position of the file. (0 is program to run.) if (inotify_add_watch(fds.fd, path, mask) < 0) perror_exit_raw(path); } for (;;) { int ret = 0, len; void *buf = 0; struct inotify_event *event; // Read next event(s) ret = poll(&fds, 1, -1); if (ret < 0 && errno == EINTR) continue; if (ret <= 0) break; xioctl(fds.fd, FIONREAD, &len); event = buf = xmalloc(len); len = readall(fds.fd, buf, len); // Loop through set of events. for (;;) { int left = len - (((char *)event)-(char *)buf), size = sizeof(struct inotify_event); // Don't dereference event if ->len is off end of bufer if (left >= size) size += event->len; if (left < size) break; if (event->mask) { char *s = toybuf, *m; for (m = masklist; *m; m++) if (event->mask & (1<<(m-masklist))) *s++ = *m; *s = 0; if (**prog_args == '-' && !prog_args[0][1]) { xprintf("%s\t%s\t%s\n" + 3*!event->len, toybuf, toys.optargs[event->wd], event->name); } else { prog_args[1] = toybuf; prog_args[2] = toys.optargs[event->wd]; prog_args[3] = event->len ? event->name : 0; xrun(prog_args); } if (event->mask & IN_IGNORED) { if (--toys.optc <= 0) { free(buf); goto done; } inotify_rm_watch(fds.fd, event->wd); } } event = (void*)(size + (char*)event); } free(buf); } done: toys.exitval = !!toys.signal; }
/* * Parses a file with an existing JParser. */ gboolean j_parse_more(JParser * p, const gchar * path, GError ** error) { gboolean ret = FALSE; gchar *all = readall(path, error); if (all == NULL) { return ret; } guint i, len = strlen(all); JParserState state = J_STATE_NEW; guint line = 1; guint start = 0; gchar *dname = NULL; GList *groups = NULL; /* stack */ for (i = 0; i < len; i++) { gchar c = all[i]; switch (state) { case J_STATE_COMMENT: if (j_isnewline(c)) { state = J_STATE_NEW; line++; } break; case J_STATE_NEW: if (j_iscomment(c)) { state = J_STATE_COMMENT; } else if (j_isnewline(c)) { /* skip empty line */ line++; } else if (j_isalpha(c)) { state = J_STATE_DIRECTIVE_NAME; start = i; } else if (j_isgroup(c)) { state = J_STATE_GROUP; } else if (!j_isspace(c)) { fill_error(error, "directive name must start with " "ascii letter, at %s:%u", path, line); goto OUT; } break; case J_STATE_DIRECTIVE_NAME: if (j_iscomment(c) || j_isnewline(c)) { dname = g_strndup(all + start, i - start); if (groups == NULL && g_strcmp0(INCLUDE_CONF, dname) == 0) { fill_error(error, "missing file path, at %s:%u", path, line); goto OUT; } JDirective *d = j_directive_alloc_take(dname, NULL); dname = NULL; if (groups == NULL) { j_parser_append_directive(p, d); } else { j_group_append_directive((JGroup *) groups->data, d); } if (j_iscomment(c)) { state = J_STATE_COMMENT; } else { state = J_STATE_NEW; line++; } } else if (j_isspace(c)) { state = J_STATE_DIRECTIVE_NAME_END; dname = g_strndup(all + start, i - start); } else if (!j_isname(c)) { fill_error(error, "directive name must only contain letters," " digits or underline, at %s:%u", path, line); goto OUT; } break; case J_STATE_DIRECTIVE_NAME_END: if (j_iscomment(c) || j_isnewline(c)) { if (groups == NULL && g_strcmp0(INCLUDE_CONF, dname) == 0) { fill_error(error, "missing file path, at %s:%u", path, line); goto OUT; } JDirective *d = j_directive_alloc_take(dname, NULL); if (groups == NULL) { j_parser_append_directive(p, d); } else { j_group_append_directive((JGroup *) groups->data, d); } dname = NULL; if (j_iscomment(c)) { state = J_STATE_COMMENT; } else { state = J_STATE_NEW; line++; } } else if (!j_isspace(c)) { state = J_STATE_DIRECTIVE_VALUE; start = i; } break; case J_STATE_DIRECTIVE_VALUE: if (j_iscomment(c) || j_isnewline(c)) { if (groups == NULL && g_strcmp0(INCLUDE_CONF, dname) == 0) { gchar *path = g_strstrip(g_strndup(all + start, i - start)); gboolean more = j_parse_more(p, path, error); g_free(path); if (!more) { goto OUT; } g_free(dname); } else { JDirective *d = j_directive_alloc_take(dname, g_strndup(all + start, i - start)); if (groups == NULL) { j_parser_append_directive(p, d); } else { j_group_append_directive((JGroup *) groups->data, d); } } dname = NULL; if (j_iscomment(c)) { state = J_STATE_COMMENT; } else { state = J_STATE_NEW; line++; } } break; case J_STATE_GROUP: if (j_isgroupend(c)) { state = J_STATE_GROUP_END; } else if (j_isspace(c)) { state = J_STATE_GROUP_START; } else if (j_isalpha(c)) { state = J_STATE_GROUP_START_NAME; start = i; } else { fill_error(error, "unexpected character %c, at %s:%u", c, path, line); goto OUT; } break; case J_STATE_GROUP_START: if (j_isalpha(c)) { state = J_STATE_GROUP_START_NAME; start = i; } else if (!j_isspace(c)) { fill_error(error, "unexpected character %c, at %s:%u", c, path, line); goto OUT; } break; case J_STATE_GROUP_START_NAME: if (j_iscomment(c)) { fill_error(error, "unexpected character %c in group name, at %s:%u", c, path, line); goto OUT; } else if (j_isnewline(c)) { fill_error(error, "unexpected EOL at %s:%u", path, line); goto OUT; } else if (j_isclose(c)) { JGroup *g = j_group_alloc_take(g_strndup(all + start, i - start), NULL); if (groups == NULL) { g = j_parser_append_group(p, g); } else { g = j_group_append_group((JGroup *) groups->data, g); } groups = g_list_prepend(groups, g); state = J_STATE_NEW; } else if (j_isspace(c)) { state = J_STATE_GROUP_START_NAME_END; dname = g_strndup(all + start, i - start); } else if (!j_isname(c)) { fill_error(error, "unexpected character %c, at %s:%u", c, path, line); goto OUT; } break; case J_STATE_GROUP_START_NAME_END: if (j_iscomment(c)) { fill_error(error, "unexpected character %c, at %s:%u", c, path, line); goto OUT; } else if (j_isnewline(c)) { fill_error(error, "unexpected EOL at %s:%u", path, line); goto OUT; } else if (j_isclose(c)) { JGroup *g = j_group_alloc_take(dname, NULL); if (groups == NULL) { g = j_parser_append_group(p, g); } else { g = j_group_append_group((JGroup *) groups->data, g); } groups = g_list_prepend(groups, g); dname = NULL; state = J_STATE_NEW; } else if (!j_isspace(c)) { state = J_STATE_GROUP_START_VALUE; start = i; } break; case J_STATE_GROUP_START_VALUE: if (j_iscomment(c)) { fill_error(error, "unexpected character %c at %s:%u", c, path, line); goto OUT; } else if (j_isnewline(c)) { fill_error(error, "unexpected EOL at %s:%u", path, line); goto OUT; } else if (j_isclose(c)) { JGroup *g = j_group_alloc_take(dname, g_strndup(all + start, i - start)); if (groups == NULL) { g = j_parser_append_group(p, g); } else { g = j_group_append_group((JGroup *) groups->data, g); } groups = g_list_prepend(groups, g); dname = NULL; state = J_STATE_NEW; } break; case J_STATE_GROUP_END: if (j_isalpha(c)) { state = J_STATE_GROUP_END_NAME; start = i; } else if (!j_isspace(c)) { fill_error(error, "unexpected character %c at %s:%u", path, line); goto OUT; } break; case J_STATE_GROUP_END_NAME: if (j_isspace(c)) { dname = g_strndup(all + start, i - start); state = J_STATE_GROUP_END_NAME_END; } else if (j_isclose(c)) { dname = g_strndup(all + start, i - start); if (groups) { JGroup *g = (JGroup *) groups->data; if (g_strcmp0(dname, j_group_get_name(g))) { fill_error(error, "group name doesn't match, at %s, %u", path, line); goto OUT; } GList *next = g_list_next(groups); g_list_free1(groups); groups = next; g_free(dname); dname = NULL; } else { fill_error(error, "unexpected group end, at %s:%u", path, line); goto OUT; } state = J_STATE_NEW; } else if (!j_isname(c)) { fill_error(error, "unexpected character %c in group name, at %s:%u", c, path, line); goto OUT; } break; case J_STATE_GROUP_END_NAME_END: if (j_isclose(c)) { dname = g_strndup(all + start, i - start); if (groups) { JGroup *g = (JGroup *) groups->data; if (g_strcmp0(dname, j_group_get_name(g))) { fill_error(error, "group name doesn't match, at %s, %u", path, line); goto OUT; } GList *next = g_list_next(groups); g_list_free1(groups); groups = next; g_free(dname); dname = NULL; } else { fill_error(error, "unexpected group end, at %s:%u", path, line); goto OUT; } state = J_STATE_NEW; } else if (!j_isspace(c)) { fill_error(error, "unexpected character %c, at %s:%u", path, line); goto OUT; } break; } } if (state != J_STATE_NEW) { fill_error(error, "unexpected EOF at %s", path); goto OUT; } else if (groups != NULL) { fill_error(error, "missing group end at %s", path); goto OUT; } ret = TRUE; OUT: g_free(all); g_list_free(groups); g_free(dname); return ret; }