/* return a piece of message starting at `offset' */ extern int m_get(message *mp, long offset, char **pp) { static char buf[4*1024]; /* * are we past eof? */ if(offset >= mp->size) return 0; /* * are we in the virtual memory portion? */ if(offset < s_len(mp->body)){ *pp = mp->body->base + offset; return mp->body->ptr - mp->body->base - offset; } /* * read it from the temp file */ offset -= s_len(mp->body); if(mp->fd < 0) return -1; if(seek(mp->fd, offset, 0)<0) return -1; *pp = buf; return read(mp->fd, buf, sizeof buf); }
/* * print out a header line, expanding any domainless addresses into * address@him */ char* bprintnode(Biobuf *b, Node *p, int *cntp) { int len; *cntp = 0; if(p->s){ if(p->addr && strchr(s_to_c(p->s), '@') == nil){ if(Bprint(b, "%s@%s", s_to_c(p->s), him) < 0) return nil; *cntp += s_len(p->s) + 1 + strlen(him); } else { len = s_len(p->s); if(Bwrite(b, s_to_c(p->s), len) < 0) return nil; *cntp += len; } }else{ if(Bputc(b, p->c) < 0) return nil; ++*cntp; } if(p->white) { len = s_len(p->white); if(Bwrite(b, s_to_c(p->white), len) < 0) return nil; *cntp += len; } return p->end+1; }
void main(int argc, char **argv) { int i; Biobuf *b; String *h; Whist *doc; ARGBEGIN{ default: usage(); case 'd': wikidir = EARGF(usage()); break; }ARGEND if(argc != 1) usage(); if((b = Bopen(argv[0], OREAD)) == nil) sysfatal("Bopen: %r"); if((doc = Brdwhist(b)) == nil) sysfatal("Brdwtxt: %r"); h = nil; for(i=0; i<doc->ndoc; i++){ print("__________________ %d ______________\n", i); if((h = pagetext(s_reset(h), doc->doc[i].wtxt, 1)) == nil) sysfatal("wiki2html: %r"); write(1, s_to_c(h), s_len(h)); } exits(0); }
/* send message filtering Reply-to out of messages */ void printmsg(int fd, String *msg, char *replyto, char *listname) { Field *f, *subject; Node *p; char *cp, *ocp; subject = nil; cp = s_to_c(msg); for(f = firstfield; f; f = f->next){ ocp = cp; for(p = f->node; p; p = p->next) cp = p->end+1; if(f->node->c == REPLY_TO) continue; if(f->node->c == PRECEDENCE) continue; if(f->node->c == SUBJECT){ subject = f; continue; } write(fd, ocp, cp-ocp); } printsubject(fd, subject, listname); fprint(fd, "Reply-To: %s\nPrecedence: bulk\n", replyto); write(fd, cp, s_len(msg) - (cp - s_to_c(msg))); }
/* if the mailbox exists, cat the mail to the end of it */ void appendtoarchive(char* listname, String *firstline, String *msg) { String *mbox; int fd; mbox = s_new(); mboxpath("mbox", listname, mbox, 0); if(access(s_to_c(mbox), 0) < 0) return; fd = open(s_to_c(mbox), OWRITE); if(fd < 0) return; s_append(msg, "\n"); write(fd, s_to_c(firstline), s_len(firstline)); write(fd, s_to_c(msg), s_len(msg)); }
char *RQ_GetHeader(ReqInfo *req, char *header) { int len = array_len(req->headers), i; for (i=0; i<len/2; i++) { if (req->headers[i*2] && !strcncmp(req->headers[i*2], header, s_len(req->headers[i*2]), strlen(header))) return i*2+1 < len ? req->headers[i*2+1] : NULL; } return NULL; }
/* * walk up the tree building a Unix style path */ static void unixpath(Node *node, String *path) { if(node == node->parent){ s_append(path, s_to_c(remrootpath)); return; } unixpath(node->parent, path); if(s_len(path) > 0 && strcmp(s_to_c(path), "/") != 0) s_append(path, "/"); s_append(path, s_to_c(node->remname)); }
/* * walk up the tree building a MVS style path */ static void mvspath(Node *node, String *path) { if(node == node->parent){ s_append(path, s_to_c(remrootpath)); return; } mvspath(node->parent, path); if(s_len(path) > 0) s_append(path, "."); s_append(path, s_to_c(node->remname)); }
void main(int argc, char **argv) { int t; int parse; String *h; Whist *doc; rfork(RFNAMEG); t = Tpage; ARGBEGIN{ default: usage(); case 'd': wikidir = EARGF(usage()); break; case 'h': t = Thistory; break; case 'o': t = Toldpage; break; case 'D': t = Tdiff; break; case 'P': parse = 1; }ARGEND if(argc != 1) usage(); if(t == Thistory || t==Tdiff) doc = gethistory(atoi(argv[0])); else doc = getcurrent(atoi(argv[0])); if(doc == nil) sysfatal("doc: %r"); if(parse){ printpage(doc->doc->wtxt); exits(0); } if((h = tohtml(doc, doc->doc+doc->ndoc-1, t)) == nil) sysfatal("wiki2html: %r"); write(1, s_to_c(h), s_len(h)); exits(0); }
static int readstr(char *delim, char *s, int allow0) { int r; r = rreadstr(delim, s); if(r == Terror) return r; if(!allow0 && s_len(sbuf) == 0){ yyerror("empty string"); return Terror; } return r; }
/* * get a line that ends in crnl or cr, turn terminating crnl into a nl * * return 0 on EOF */ static int getcrnl(String *s, Biobuf *fp) { int c; for(;;){ c = Bgetc(fp); if(debug) { seek(2, 0, 2); fprint(2, "%c", c); } switch(c){ case 0: break; case -1: goto out; case '\r': c = Bgetc(fp); if(c == '\n'){ if(debug) { seek(2, 0, 2); fprint(2, "%c", c); stamp(); } s_putc(s, '\n'); goto out; } Bungetc(fp); s_putc(s, '\r'); break; case '\n': s_putc(s, c); goto out; default: s_putc(s, c); break; } } out: s_terminate(s); return s_len(s); }
static int readname(char *s) { int c; s_reset(sbuf); if(s) skip(s); while((c=GETC()) >= 0 && (isalnum(c) || c == '-')) s_putc(sbuf, c); if(c == Beof){ yyerror("eof in id/class"); return Terror; } UNGETC(c); if(s_len(sbuf) == 0){ yyerror("empty name"); return Terror; } s_terminate(sbuf); return Tstring; }
String * s_dec64(String *sin) { int lin, lout; String *sout; lin = s_len(sin); /* * if the string is coming from smtpd.y, it will have no nl. * if it is coming from getcrnl below, it will have an nl. */ if (*(s_to_c(sin)+lin-1) == '\n') lin--; sout = s_newalloc(lin+1); lout = dec64((uchar *)s_to_c(sout), lin, s_to_c(sin), lin); if (lout < 0) { s_free(sout); return nil; } sout->ptr = sout->base + lout; s_terminate(sout); return sout; }
void iconv(const char* to_charset, const char* from_charset, std::string& target, const std::string& source) throw (std::runtime_error) { iconv_t cd(::iconv_open(to_charset, from_charset)); if (cd == reinterpret_cast<iconv_t>(-1) ) throw std::runtime_error("iconv_open failed"); size_t s_len(source.size()); char* s_ptr(const_cast<char*>(source.data())); size_t max_o_len = s_len * 5; size_t o_len(max_o_len); char* const buf = new char[o_len]; char* o_ptr(buf); ::iconv(cd, &s_ptr, &s_len, &o_ptr, &o_len); // if ((s_len != 0) || errno) { // int sys_err(errno); // throw std::runtime_error(std::string(source) + // ": Dv::Xml::iconv from " + from_charset + " to " + to_charset + " failed [" + // (sys_err ? strerror(sys_err) : "") + "]" // ); // } target.resize(0); target.append(buf, max_o_len - o_len); delete [] buf; iconv_close(cd); }
/* * Attempt to install a new page. If t==0 we are creating. * Otherwise, we are editing and t must be set to the current * version (t is the version we started with) to avoid conflicting * writes. * * If there is a conflicting write, we still write the page to * the history file, but mark it as a failed write. */ int writepage(int num, uint32_t t, String *s, char *title) { char tmp[40], tmplock[40], err[ERRMAX], hist[40], *p; int conflict, lfd, fd; Biobuf *b; String *os; sprint(tmp, "d/%d", num); sprint(tmplock, "d/L.%d", num); sprint(hist, "d/%d.hist", num); if((lfd = getlock(tmplock)) < 0) return -1; conflict = 0; if(b = wBopen(tmp, OREAD)){ Brdline(b, '\n'); /* title */ if(p = Brdline(b, '\n')) /* version */ p[Blinelen(b)-1] = '\0'; if(p==nil || p[0] != 'D'){ snprint(err, sizeof err, "bad format in extant file"); conflict = 1; }else if(strtoul(p+1, 0, 0) != t){ os = Brdstring(b); /* why read the whole file? */ p = strchr(s_to_c(s), '\n'); if(p!=nil && strcmp(p+1, s_to_c(os))==0){ /* ignore dup write */ close(lfd); s_free(os); Bterm(b); return 0; } s_free(os); snprint(err, sizeof err, "update conflict %lud != %s", t, p+1); conflict = 1; } Bterm(b); }else{ if(t != 0){ close(lfd); werrstr("did not expect to create"); return -1; } } if((fd = wopen(hist, OWRITE)) < 0){ if((fd = wcreate(hist, OWRITE, 0666)) < 0){ close(lfd); return -1; }else fprint(fd, "%s\n", title); } if(seek(fd, 0, 2) < 0 || (conflict && write(fd, "X\n", 2) != 2) || write(fd, s_to_c(s), s_len(s)) != s_len(s)){ close(fd); close(lfd); return -1; } close(fd); if(conflict){ close(lfd); voidcache(num); werrstr(err); return -1; } if((fd = wcreate(tmp, OWRITE, 0666)) < 0){ close(lfd); voidcache(num); return -1; } if(write(fd, title, strlen(title)) != strlen(title) || write(fd, "\n", 1) != 1 || write(fd, s_to_c(s), s_len(s)) != s_len(s)){ close(fd); close(lfd); voidcache(num); return -1; } close(fd); close(lfd); voidcache(num); return 0; }
void ft_putstr(char *s) { write(1, s, s_len(s)); }
/* fix 822 addresses */ static void rfc822cruft(message *mp) { Field *f; Node *p; String *body, *s; char *cp; /* * parse headers in in-core part */ yyinit(s_to_c(mp->body), s_len(mp->body)); mp->rfc822headers = 0; yyparse(); mp->rfc822headers = 1; mp->received = received; /* * remove equivalent systems in all addresses */ body = s_new(); cp = s_to_c(mp->body); for(f = firstfield; f; f = f->next){ if(f->node->c == MIMEVERSION) mp->havemime = 1; if(f->node->c == FROM) mp->havefrom = getaddr(f->node); if(f->node->c == SENDER) mp->havesender = getaddr(f->node); if(f->node->c == REPLY_TO) mp->havereplyto = getaddr(f->node); if(f->node->c == TO) mp->haveto = 1; if(f->node->c == DATE) mp->havedate = 1; if(f->node->c == SUBJECT) mp->havesubject = getstring(f->node); if(f->node->c == PRECEDENCE && f->node->next && f->node->next->next){ s = f->node->next->next->s; if(s && (strcmp(s_to_c(s), "bulk") == 0 || strcmp(s_to_c(s), "Bulk") == 0)) mp->bulk = 1; } for(p = f->node; p; p = p->next){ if(p->s){ if(p->addr){ cp = skipequiv(s_to_c(p->s)); s_append(body, cp); } else s_append(body, s_to_c(p->s)); }else{ s_putc(body, p->c); s_terminate(body); } if(p->white) s_append(body, s_to_c(p->white)); cp = p->end+1; } s_append(body, "\n"); } if(*s_to_c(body) == 0){ s_free(body); return; } if(*cp != '\n') s_append(body, "\n"); s_memappend(body, cp, s_len(mp->body) - (cp - s_to_c(mp->body))); s_terminate(body); firstfield = 0; mp->size += s_len(body) - s_len(mp->body); s_free(mp->body); mp->body = body; }
void main(int argc, char **argv) { String *msg; String *firstline; char *listname, *alfile; Waitmsg *w; int fd; char *replytoname = nil; ARGBEGIN{ case 'r': replytoname = ARGF(); break; }ARGEND; rfork(RFENVG|RFREND); if(argc < 2) usage(); alfile = argv[0]; listname = argv[1]; if(replytoname == nil) replytoname = listname; readaddrs(alfile); if(Binit(&in, 0, OREAD) < 0) sysfatal("opening input: %r"); msg = s_new(); firstline = s_new(); /* discard the 'From ' line */ if(s_read_line(&in, firstline) == nil) sysfatal("reading input: %r"); /* read up to the first 128k of the message. more is ridiculous. Not if word documents are distributed. Upped it to 2MB (pb) */ if(s_read(&in, msg, 2*1024*1024) <= 0) sysfatal("reading input: %r"); /* parse the header */ yyinit(s_to_c(msg), s_len(msg)); yyparse(); /* get the sender */ getaddrs(); if(from == nil) from = sender; if(from == nil) sysfatal("message must contain From: or Sender:"); if(strcmp(listname, s_to_c(from)) == 0) sysfatal("can't remail messages from myself"); addaddr(s_to_c(from)); /* start the mailer up and return a pipe to it */ fd = startmailer(listname); /* send message adding our own reply-to and precedence */ printmsg(fd, msg, replytoname, listname); close(fd); /* wait for mailer to end */ while(w = wait()){ if(w->msg != nil && w->msg[0]) sysfatal("%s", w->msg); free(w); } /* if the mailbox exists, cat the mail to the end of it */ appendtoarchive(listname, firstline, msg); exits(0); }
int compare_str(char *wildcard, char *check) { printf("===================================\nTesting with %s and %s\n", wildcard, check); char *wc = wildcard; int i; // get the position of the substring char substr[MAX_WILDCARD]; int escape = 0; for (i = 0; *wc != '\0'; i++, wc++) { if (*wc == '*' && *(wc-1) != '\\') { break; } substr[i] = *wc; } substr[i++] = '\0'; // check if *wc is now '\0', because that means that no '*' was found if (*wc == '\0') { printf("Couldn't find any asterisk\n===============================================\n"); return 0; } /* * If code below runs well, then the beginning of check and wildcard match */ //printf("substr: %s\n", substr); char *ch = check; for (int j = 0; j < i-1; j++) { if (*(ch+j) != substr[j]) return 0; } //printf("matching substr: %s\n", substr); // if it returned 0, then the string is not a substring of the wildcard // so, if the program still runs, we are at position i (where the * is) // and now we have to check if there is any string in place of the asterisk ch = wildcard + i; int j; for (j = 0; *ch != '\0'; j++, ch++) substr[j] = *ch; substr[j] = '\0'; // now we should have a new substr char ast[100]; // so now we have the last characters after the asterisk in substr ch = check + i - 1; int subl = s_len(substr); int subp = s_len(ch); // printf("subl: %i | subp: %i\n", subl, subp); for (j = 0; *ch != '\0'; ch++, j++, subp--) { //printf("subl: %i | subp: %i\n", subl, subp); if (subp <= subl) { if(str_eq(ch, substr)) { // printf("Calling str_eq with %p and %s\n", ch, substr); ast[j] = '\0'; printf("Hey, that's valid!\nInstead of the asterisk in %s we have %s\n=============================\n", wildcard, ast); return 1; } } ast[j] = *ch; } ast[j] = '\0'; // printf("ast: %s\n", ast); printf("Sorry, but the strings don't match\n===========================================\n"); return 0; }
/* * pipe message to mailer with the following transformations: * - change \r\n into \n. * - add sender's domain to any addrs with no domain * - add a From: if none of From:, Sender:, or Replyto: exists * - add a Received: line */ int pipemsg(int *byteswritten) { int n, nbytes, sawdot, status, nonhdr, bpr; char *cp; Field *f; Link *l; Node *p; String *hdr, *line; pipesig(&status); /* set status to 1 on write to closed pipe */ sawdot = 0; status = 0; /* * add a 'From ' line as envelope */ nbytes = 0; nbytes += Bprint(pp->std[0]->fp, "From %s %s remote from \n", s_to_c(senders.first->p), thedate()); /* * add our own Received: stamp */ nbytes += Bprint(pp->std[0]->fp, "Received: from %s ", him); if(nci->rsys) nbytes += Bprint(pp->std[0]->fp, "([%s]) ", nci->rsys); nbytes += Bprint(pp->std[0]->fp, "by %s; %s\n", me, thedate()); /* * read first 16k obeying '.' escape. we're assuming * the header will all be there. */ line = s_new(); hdr = s_new(); while(sawdot == 0 && s_len(hdr) < 16*1024){ n = getcrnl(s_reset(line), &bin); /* eof or error ends the message */ if(n <= 0) break; /* a line with only a '.' ends the message */ cp = s_to_c(line); if(n == 2 && *cp == '.' && *(cp+1) == '\n'){ sawdot = 1; break; } s_append(hdr, *cp == '.' ? cp+1 : cp); } /* * parse header */ yyinit(s_to_c(hdr), s_len(hdr)); yyparse(); /* * Look for masquerades. Let Sender: trump From: to allow mailing list * forwarded messages. */ if(fflag) nbytes += forgedheaderwarnings(); /* * add an orginator and/or destination if either is missing */ if(originator == 0){ if(senders.last == nil || senders.last->p == nil) nbytes += Bprint(pp->std[0]->fp, "From: /dev/null@%s\n", him); else nbytes += Bprint(pp->std[0]->fp, "From: %s\n", s_to_c(senders.last->p)); } if(destination == 0){ nbytes += Bprint(pp->std[0]->fp, "To: "); for(l = rcvers.first; l; l = l->next){ if(l != rcvers.first) nbytes += Bprint(pp->std[0]->fp, ", "); nbytes += Bprint(pp->std[0]->fp, "%s", s_to_c(l->p)); } nbytes += Bprint(pp->std[0]->fp, "\n"); } /* * add sender's domain to any domainless addresses * (to avoid forging local addresses) */ cp = s_to_c(hdr); for(f = firstfield; cp != nil && f; f = f->next){ for(p = f->node; cp != 0 && p; p = p->next) { bpr = 0; cp = bprintnode(pp->std[0]->fp, p, &bpr); nbytes += bpr; } if(status == 0 && Bprint(pp->std[0]->fp, "\n") < 0){ piperror = "write error"; status = 1; } nbytes++; /* for newline */ } if(cp == nil){ piperror = "sender domain"; status = 1; } /* write anything we read following the header */ nonhdr = s_to_c(hdr) + s_len(hdr) - cp; if(status == 0 && Bwrite(pp->std[0]->fp, cp, nonhdr) < 0){ piperror = "write error 2"; status = 1; } nbytes += nonhdr; s_free(hdr); /* * pass rest of message to mailer. take care of '.' * escapes. */ while(sawdot == 0){ n = getcrnl(s_reset(line), &bin); /* eof or error ends the message */ if(n <= 0) break; /* a line with only a '.' ends the message */ cp = s_to_c(line); if(n == 2 && *cp == '.' && *(cp+1) == '\n'){ sawdot = 1; break; } if(cp[0] == '.'){ cp++; n--; } nbytes += n; if(status == 0 && Bwrite(pp->std[0]->fp, cp, n) < 0){ piperror = "write error 3"; status = 1; } } s_free(line); if(sawdot == 0){ /* message did not terminate normally */ snprint(pipbuf, sizeof pipbuf, "network eof: %r"); piperror = pipbuf; if (pp->pid > 0) { syskillpg(pp->pid); /* none can't syskillpg, so try a variant */ sleep(500); syskill(pp->pid); } status = 1; } if(status == 0 && Bflush(pp->std[0]->fp) < 0){ piperror = "write error 4"; status = 1; } if (debug) { stamp(); fprint(2, "at end of message; %s .\n", (sawdot? "saw": "didn't see")); } stream_free(pp->std[0]); pp->std[0] = 0; *byteswritten = nbytes; pipesigoff(); if(status && !piperror) piperror = "write on closed pipe"; return status; }
void auth(String *mech, String *resp) { char *user, *pass, *scratch = nil; AuthInfo *ai = nil; Chalstate *chs = nil; String *s_resp1_64 = nil, *s_resp2_64 = nil, *s_resp1 = nil; String *s_resp2 = nil; if (rejectcheck()) goto bomb_out; syslog(0, "smtpd", "auth(%s, %s) from %s", s_to_c(mech), "(protected)", him); if (authenticated) { bad_sequence: rejectcount++; reply("503 5.5.2 Bad sequence of commands\r\n"); goto bomb_out; } if (cistrcmp(s_to_c(mech), "plain") == 0) { if (!passwordinclear) { rejectcount++; reply("538 5.7.1 Encryption required for requested " "authentication mechanism\r\n"); goto bomb_out; } s_resp1_64 = resp; if (s_resp1_64 == nil) { reply("334 \r\n"); s_resp1_64 = s_new(); if (getcrnl(s_resp1_64, &bin) <= 0) goto bad_sequence; } s_resp1 = s_dec64(s_resp1_64); if (s_resp1 == nil) { rejectcount++; reply("501 5.5.4 Cannot decode base64\r\n"); goto bomb_out; } memset(s_to_c(s_resp1_64), 'X', s_len(s_resp1_64)); user = s_to_c(s_resp1) + strlen(s_to_c(s_resp1)) + 1; pass = user + strlen(user) + 1; ai = auth_userpasswd(user, pass); authenticated = ai != nil; memset(pass, 'X', strlen(pass)); goto windup; } else if (cistrcmp(s_to_c(mech), "login") == 0) { if (!passwordinclear) { rejectcount++; reply("538 5.7.1 Encryption required for requested " "authentication mechanism\r\n"); goto bomb_out; } if (resp == nil) { reply("334 VXNlcm5hbWU6\r\n"); s_resp1_64 = s_new(); if (getcrnl(s_resp1_64, &bin) <= 0) goto bad_sequence; } reply("334 UGFzc3dvcmQ6\r\n"); s_resp2_64 = s_new(); if (getcrnl(s_resp2_64, &bin) <= 0) goto bad_sequence; s_resp1 = s_dec64(s_resp1_64); s_resp2 = s_dec64(s_resp2_64); memset(s_to_c(s_resp2_64), 'X', s_len(s_resp2_64)); if (s_resp1 == nil || s_resp2 == nil) { rejectcount++; reply("501 5.5.4 Cannot decode base64\r\n"); goto bomb_out; } ai = auth_userpasswd(s_to_c(s_resp1), s_to_c(s_resp2)); authenticated = ai != nil; memset(s_to_c(s_resp2), 'X', s_len(s_resp2)); windup: if (authenticated) { /* if you authenticated, we trust you despite your IP */ trusted = 1; reply("235 2.0.0 Authentication successful\r\n"); } else { rejectcount++; reply("535 5.7.1 Authentication failed\r\n"); syslog(0, "smtpd", "authentication failed: %r"); } goto bomb_out; } else if (cistrcmp(s_to_c(mech), "cram-md5") == 0) { int chal64n; char *resp, *t; chs = auth_challenge("proto=cram role=server"); if (chs == nil) { rejectcount++; reply("501 5.7.5 Couldn't get CRAM-MD5 challenge\r\n"); goto bomb_out; } scratch = malloc(chs->nchal * 2 + 1); chal64n = enc64(scratch, chs->nchal * 2, (uchar *)chs->chal, chs->nchal); scratch[chal64n] = 0; reply("334 %s\r\n", scratch); s_resp1_64 = s_new(); if (getcrnl(s_resp1_64, &bin) <= 0) goto bad_sequence; s_resp1 = s_dec64(s_resp1_64); if (s_resp1 == nil) { rejectcount++; reply("501 5.5.4 Cannot decode base64\r\n"); goto bomb_out; } /* should be of form <user><space><response> */ resp = s_to_c(s_resp1); t = strchr(resp, ' '); if (t == nil) { rejectcount++; reply("501 5.5.4 Poorly formed CRAM-MD5 response\r\n"); goto bomb_out; } *t++ = 0; chs->user = resp; chs->resp = t; chs->nresp = strlen(t); ai = auth_response(chs); authenticated = ai != nil; goto windup; } rejectcount++; reply("501 5.5.1 Unrecognised authentication type %s\r\n", s_to_c(mech)); bomb_out: if (ai) auth_freeAI(ai); if (chs) auth_freechal(chs); if (scratch) free(scratch); if (s_resp1) s_free(s_resp1); if (s_resp2) s_free(s_resp2); if (s_resp1_64) s_free(s_resp1_64); if (s_resp2_64) s_free(s_resp2_64); }