int main(void) { char dollars[100] = { "" }; char pennies[100] = { "" }; puts("Enter a sum in pennies (with 1 decimal)"); printf("without any commas or dots: "); fgets(pennies, 99, stdin); commas(dollars, pennies); puts("K. That sum, nicely arranged is"); printf("\n%s\n\n", dollars); return 0; }
static word fetch_file(void) { // Returns 0=Success with relevant file open on fp_result // Or !0 = failure and file is closed. // DANGER: In failure case, fp_result is INVALID and may not be null. char zs[256], filepathz[256], filepath[256], url[256]; time_t now, when; struct tm * broken; static char * weekdays[] = { "sun", "mon", "tue", "wed", "thu", "fri", "sat" }; stats[Fetches]++; now = time(NULL); if(!opt_filename) { static CURL * curlh; struct curl_slist * slist; if(!(curlh = curl_easy_init())) { _log(CRITICAL, "fetch_file(): Failed to obtain libcurl easy handle."); return 1; } curl_easy_setopt(curlh, CURLOPT_WRITEFUNCTION, cif_write_data); slist = NULL; slist = curl_slist_append(slist, "Cache-Control: no-cache"); if(!slist) { _log(MAJOR,"fetch_file(): Failed to create slist."); return 1; } // Build URL when = now - 24*60*60; broken = localtime(&when); // Note broken contains "yesterday" if(opt_url) { strcpy(url, opt_url); } else { if(fetch_all) { sprintf(url, "https://datafeeds.networkrail.co.uk/ntrod/CifFileAuthenticate?type=CIF_ALL_FULL_DAILY&day=toc-full"); } else { sprintf(url, "https://datafeeds.networkrail.co.uk/ntrod/CifFileAuthenticate?type=CIF_ALL_UPDATE_DAILY&day=toc-update-%s", weekdays[broken->tm_wday]); } } sprintf(zs, "Fetching \"%s\".", url); _log(GENERAL, zs); if(opt_url || debug) { sprintf(filepathz, "/tmp/tscdb-cif-fetch-%ld.gz", now); sprintf(filepath, "/tmp/tscdb-cif-fetch-%ld", now); } else if(fetch_all) { sprintf(filepathz, "/tmp/tscdb-cif-all-%02d-%02d-%02d-%s.gz", broken->tm_year%100, broken->tm_mon + 1, broken->tm_mday, weekdays[broken->tm_wday]); sprintf(filepath, "/tmp/tscdb-cif-all-%02d-%02d-%02d-%s", broken->tm_year%100, broken->tm_mon + 1, broken->tm_mday, weekdays[broken->tm_wday]); } else { sprintf(filepathz, "/tmp/tscdb-cif-%02d-%02d-%02d-%s.gz", broken->tm_year%100, broken->tm_mon + 1, broken->tm_mday, weekdays[broken->tm_wday]); sprintf(filepath, "/tmp/tscdb-cif-%02d-%02d-%02d-%s", broken->tm_year%100, broken->tm_mon + 1, broken->tm_mday, weekdays[broken->tm_wday]); } if(!(fp_result = fopen(filepathz, "w"))) { sprintf(zs, "Failed to open \"%s\" for writing.", filepathz); _log(MAJOR, zs); return 1; } curl_easy_setopt(curlh, CURLOPT_HTTPHEADER, slist); // Set timeouts curl_easy_setopt(curlh, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt(curlh, CURLOPT_FTP_RESPONSE_TIMEOUT, 128L); curl_easy_setopt(curlh, CURLOPT_TIMEOUT, 128L); curl_easy_setopt(curlh, CURLOPT_CONNECTTIMEOUT, 128L); // Debugging prints. // curl_easy_setopt(curlh, CURLOPT_VERBOSE, 1L); // URL and login curl_easy_setopt(curlh, CURLOPT_URL, url); sprintf(zs, "%s:%s", conf[conf_nr_user], conf[conf_nr_password]); curl_easy_setopt(curlh, CURLOPT_USERPWD, zs); curl_easy_setopt(curlh, CURLOPT_FOLLOWLOCATION, 1L); // On receiving a 3xx response, follow the redirect. total_bytes = 0; CURLcode result; if((result = curl_easy_perform(curlh))) { _log(MAJOR, "fetch_file(): curl_easy_perform() returned error %d: %s.", result, curl_easy_strerror(result)); if(opt_insecure && (result == 51 || result == 60)) { _log(MAJOR, "Retrying download in insecure mode."); // SSH failure, retry without curl_easy_setopt(curlh, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curlh, CURLOPT_SSL_VERIFYHOST, 0L); used_insecure = true; if((result = curl_easy_perform(curlh))) { _log(MAJOR, "fetch_file(): In insecure mode curl_easy_perform() returned error %d: %s.", result, curl_easy_strerror(result)); if(fp_result) fclose(fp_result); fp_result = NULL; return 1; } } else { if(fp_result) fclose(fp_result); fp_result = NULL; return 1; } } char * actual_url; if(!curl_easy_getinfo(curlh, CURLINFO_EFFECTIVE_URL, &actual_url) && actual_url) { _log(GENERAL, "Download was redirected to \"%s\".", actual_url); } if(fp_result) fclose(fp_result); fp_result = NULL; if(curlh) curl_easy_cleanup(curlh); curlh = NULL; if(slist) curl_slist_free_all(slist); slist = NULL; sprintf(zs, "Received %s bytes of compressed CIF updates.", commas(total_bytes)); _log(GENERAL, zs); if(total_bytes == 0) return 1; _log(GENERAL, "Decompressing data..."); sprintf(zs, "/bin/gunzip -f %s", filepathz); char * rc; if((rc = system_call(zs))) { _log(MAJOR, "Failed to uncompress file: %s", rc); if((fp_result = fopen(filepathz, "r"))) { char error_message[2048]; size_t length; if((length = fread(error_message, 1, 2047, fp_result)) && error_message[0] == '<') { error_message[length] = '\0'; _log(MAJOR, "Received message:\n%s", error_message); } fclose(fp_result); } return 1; } _log(GENERAL, "Decompressed."); } else { strcpy(filepath, opt_filename); } if(!(fp_result = fopen(filepath, "r"))) { _log(MAJOR, "Failed to open \"%s\" for reading.", filepath); return 1; } // Check if it's really an update { sprintf(zs, "grep -q \\\"Delete\\\" %s", filepath); word not_update = system(zs); if(not_update && (total_bytes < 32000000L)) not_update = false; _log(test_mode?GENERAL:DEBUG, "File is an update assessment: %s.", not_update?"File is not an update":"File is an update"); if(fetch_all && !not_update) { _log(MAJOR, "Requested full timetable looks like an update."); fclose(fp_result); return 1; } if(!fetch_all && not_update) { _log(MAJOR, "Requested update looks like a full timetable."); fclose(fp_result); return 1; } } // Read enough of the file to find the datestamp char front[256]; regmatch_t matches[3]; if(!fread(front, 1, sizeof(front), fp_result)) { fclose(fp_result); return 1; } else { front[255] = '\0'; if(regexec(&match[0], front, 2, matches, 0)) { // Failed _log(MAJOR, "Failed to derive CIF file timestamp."); fclose(fp_result); return 1; } else { char zstamp[256]; extract_match(front, matches, 1, zstamp, sizeof(zstamp)); time_t stamp = atoi(zstamp); _log(test_mode?GENERAL:DEBUG, "Recovered timestamp: %s", time_text(stamp, 0)); _log(test_mode?GENERAL:DEBUG, "Stored in file \"%s\"", filepath); if(regexec(&match[1], front, 2, matches, 0)) { _log(MINOR, "Failed to derive CIF file sequence number."); } else { extract_match(front, matches, 1, zstamp, sizeof(zstamp)); stats[Sequence] = atol(zstamp); _log(test_mode?GENERAL:DEBUG, "Sequence number: %s", commas_q(stats[Sequence])); } if(!test_mode && !opt_url && !opt_filename && (now < stamp || now - stamp > 36*60*60)) { _log(MAJOR, "Timestamp %s is incorrect. Received sequence number %d.", time_text(stamp, true), stats[Sequence]); fclose(fp_result); stats[Sequence] = 0; return 1; } } } fseeko(fp_result, 0, SEEK_SET); return 0; }
void mesgsend(Message *m) { char *s, *body, *to; int i, j, h, n, natt, p[2]; struct Exec *e; Channel *sync; int first, nfld, delit, ofd; char *copy, *fld[100], *now; body = winreadbody(m->w, &n); /* assemble to: list from first line, to: line, and cc: line */ nto = 0; natt = 0; ncc = 0; nbcc = 0; first = 1; to = body; for(;;){ for(s=to; *s!='\n'; s++) if(*s == '\0'){ free(body); return; } if(s++ == to) /* blank line */ break; /* make copy of line to tokenize */ copy = emalloc(s-to); memmove(copy, to, s-to); copy[s-to-1] = '\0'; nfld = tokenizec(copy, fld, nelem(fld), ", \t"); if(nfld == 0){ free(copy); break; } n -= s-to; switch(h = whichheader(fld[0])){ case TO: case FROM: delit = 1; commas(to+strlen(fld[0]), s-1); for(i=1; i<nfld && nto<nelem(tolist); i++) if(!addressed(fld[i])) tolist[nto++] = estrdup(fld[i]); break; case BCC: delit = 1; commas(to+strlen(fld[0]), s-1); for(i=1; i<nfld && nbcc<nelem(bcclist); i++) if(!addressed(fld[i])) bcclist[nbcc++] = estrdup(fld[i]); break; case CC: delit = 1; commas(to+strlen(fld[0]), s-1); for(i=1; i<nfld && ncc<nelem(cclist); i++) if(!addressed(fld[i])) cclist[ncc++] = estrdup(fld[i]); break; case ATTACH: case INCLUDE: delit = 1; for(i=1; i<nfld && natt<nelem(attlist); i++){ attlist[natt] = estrdup(fld[i]); included[natt++] = (h == INCLUDE); } break; default: if(first){ delit = 1; for(i=0; i<nfld && nto<nelem(tolist); i++) tolist[nto++] = estrdup(fld[i]); }else /* ignore it */ delit = 0; break; } if(delit){ /* delete line from body */ memmove(to, s, n+1); }else to = s; free(copy); first = 0; } ofd = open(outgoing, OWRITE|OCEXEC); /* no error check necessary */ if(ofd > 0){ /* From dhog Fri Aug 24 22:13:00 EDT 2001 */ now = ctime(time(0)); seek(ofd, 0, 2); fprint(ofd, "From %s %s", user, now); fprint(ofd, "From: %s\n", user); fprint(ofd, "Date: %s", now); for(i=0; i<natt; i++) if(included[i]) fprint(ofd, "Include: %s\n", attlist[i]); else fprint(ofd, "Attach: %s\n", attlist[i]); /* needed because mail is by default Latin-1 */ fprint(ofd, "Content-Type: text/plain; charset=\"UTF-8\"\n"); fprint(ofd, "Content-Transfer-Encoding: 8bit\n"); } e = emalloc(sizeof(struct Exec)); if(pipe(p) < 0) error("can't create pipe: %r"); e->p[0] = p[0]; e->p[1] = p[1]; e->prog = unsharp("#9/bin/upas/marshal"); e->argv = emalloc((1+1+2+4*natt+1)*sizeof(char*)); e->argv[0] = estrdup("marshal"); e->argv[1] = estrdup("-8"); j = 2; if(m->replyname){ e->argv[j++] = estrdup("-R"); e->argv[j++] = estrstrdup(mbox.name, m->replyname); } for(i=0; i<natt; i++){ if(included[i]) e->argv[j++] = estrdup("-A"); else e->argv[j++] = estrdup("-a"); e->argv[j++] = estrdup(attlist[i]); } sync = chancreate(sizeof(int), 0); e->sync = sync; proccreate(execproc, e, EXECSTACK); recvul(sync); /* close(p[0]); */ /* using marshal -8, so generate rfc822 headers */ if(nto > 0){ print2(p[1], ofd, "To: "); for(i=0; i<nto-1; i++) print2(p[1], ofd, "%s, ", tolist[i]); print2(p[1], ofd, "%s\n", tolist[i]); } if(ncc > 0){ print2(p[1], ofd, "CC: "); for(i=0; i<ncc-1; i++) print2(p[1], ofd, "%s, ", cclist[i]); print2(p[1], ofd, "%s\n", cclist[i]); } if(nbcc > 0){ print2(p[1], ofd, "BCC: "); for(i=0; i<nbcc-1; i++) print2(p[1], ofd, "%s, ", bcclist[i]); print2(p[1], ofd, "%s\n", bcclist[i]); } i = strlen(body); if(i > 0) write2(p[1], ofd, body, i, 1); /* guarantee a blank line, to ensure attachments are separated from body */ if(i==0 || body[i-1]!='\n') write2(p[1], ofd, "\n\n", 2, 0); else if(i>1 && body[i-2]!='\n') write2(p[1], ofd, "\n", 1, 0); /* these look like pseudo-attachments in the "outgoing" box */ if(ofd>0 && natt>0){ for(i=0; i<natt; i++) if(included[i]) fprint(ofd, "=====> Include: %s\n", attlist[i]); else fprint(ofd, "=====> Attach: %s\n", attlist[i]); } if(ofd > 0) write(ofd, "\n", 1); for(i=0; i<natt; i++) free(attlist[i]); close(ofd); close(p[1]); free(body); if(m->replyname != nil) mesgmenumark(mbox.w, m->replyname, "\t[replied]"); if(m->name[0] == '/') s = estrdup(m->name); else s = estrstrdup(mbox.name, m->name); s = egrow(s, "-R", nil); winname(m->w, s); free(s); winclean(m->w); /* mark message unopened because it's no longer the original message */ m->opened = 0; }
void mesgpost(Article *m) { Biobuf *b; char *p, *ep; int isfirst, ishdr, havegroup, havefrom; p = estrstrdup(dir, "post"); if((b = Bopen(p, OWRITE)) == nil){ fprint(2, "cannot open %s: %r\n", p); free(p); return; } free(p); winopenbody(m->w, OREAD); ishdr = 1; isfirst = 1; havegroup = havefrom = 0; while(p = Brdline(m->w->body, '\n')){ ep = p+Blinelen(m->w->body); if(ishdr && p+1==ep){ if(!havegroup) Bprint(b, "Newsgroups: %s\n", group); if(!havefrom) Bprint(b, "From: %s\n", from); ishdr = 0; } if(ishdr){ ep[-1] = '\0'; if(isfirst && strchr(p, ':')==0){ /* group list */ commas(p, ep); Bprint(b, "newsgroups: %s\n", p); havegroup = 1; isfirst = 0; continue; } if(cistrncmp(p, "newsgroup:", 10)==0){ commas(skip(p, "newsgroup:"), ep); Bprint(b, "newsgroups: %s\n", skip(p, "newsgroup:")); havegroup = 1; continue; } if(cistrncmp(p, "newsgroups:", 11)==0){ commas(skip(p, "newsgroups:"), ep); Bprint(b, "newsgroups: %s\n", skip(p, "newsgroups:")); havegroup = 1; continue; } if(cistrncmp(p, "from:", 5)==0) havefrom = 1; ep[-1] = '\n'; } Bwrite(b, p, ep-p); } winclosebody(m->w); Bflush(b); if(write(Bfildes(b), "", 0) == 0) winclean(m->w); else fprint(2, "post: %r\n"); Bterm(b); }