-/* SCCS Id: @(#)rumors.c 3.5 1996/04/20 */
+/* SCCS Id: @(#)rumors.c 3.5 2006/05/05 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
* this also happens with real fortune cookies. -dgk
*/
-/* 3.1
+/* 3.5
+ * The rumors file consists of a "do not edit" line, then a line containing
+ * three sets of three counts (first two in decimal, third in hexadecimal).
+ * The first set has the number of true rumors, the count in bytes for all
+ * true rumors, and the file offset to the first one. The second set has
+ * the same group of numbers for the false rumors. The third set has 0 for
+ * count, 0 for size, and the file offset for end-of-file. The offset of
+ * the first true rumor plus the size of the true rumors matches the offset
+ * of the first false rumor. Likewise, the offset of the first false rumor
+ * plus the size of the false rumors matches the offset for end-of-file.
+ */
+
+/* 3.1 [now obsolete for rumors but still accurate for oracles]
* The rumors file consists of a "do not edit" line, a hexadecimal number
* giving the number of bytes of useful/true rumors, followed by those
* true rumors (one per line), followed by the useless/false/misleading/cute
init_rumors(fp)
dlb *fp;
{
+ static const char rumors_header[] = "%d,%ld,%lx;%d,%ld,%lx;0,0,%lx\n";
+ int true_count, false_count; /* in file but not used here */
+ long eof_offset;
char line[BUFSZ];
(void) dlb_fgets(line, sizeof line, fp); /* skip "don't edit" comment */
(void) dlb_fgets(line, sizeof line, fp);
- if (sscanf(line, "%6lx\n", &true_rumor_size) == 1 &&
- true_rumor_size > 0L) {
- (void) dlb_fseek(fp, 0L, SEEK_CUR);
- true_rumor_start = dlb_ftell(fp);
- true_rumor_end = true_rumor_start + true_rumor_size;
- (void) dlb_fseek(fp, 0L, SEEK_END);
- false_rumor_end = dlb_ftell(fp);
- false_rumor_start = true_rumor_end; /* ok, so it's redundant... */
- false_rumor_size = false_rumor_end - false_rumor_start;
- } else
+ if (sscanf(line, rumors_header,
+ &true_count, &true_rumor_size, &true_rumor_start,
+ &false_count, &false_rumor_size, &false_rumor_start,
+ &eof_offset) == 7 &&
+ true_rumor_size > 0L && false_rumor_size > 0L) {
+ true_rumor_end = true_rumor_start + true_rumor_size;
+ /* assert( true_rumor_end == false_rumor_start ); */
+ false_rumor_end = false_rumor_start + false_rumor_size;
+ /* assert( false_rumor_end == eof_offset ); */
+ } else {
true_rumor_size = -1L; /* init failed */
+ (void) dlb_fclose(fp);
+ }
}
/* exclude_cookie is a hack used because we sometimes want to get rumors in a
winid tmpwin;
char *endp, line[BUFSZ], xbuf[BUFSZ], rumor_buf[BUFSZ];
- if (true_rumor_size < 0L) /* we couldn't open RUMORFILE */
+ if (true_rumor_size < 0L) { /* we couldn't open RUMORFILE */
+ no_rumors:
+ pline("rumors not accessible.");
return;
+ }
rumors = dlb_fopen(RUMORFILE, "r");
rumor_buf[0] = '\0';
if (true_rumor_size == 0L) { /* if this is 1st outrumor() */
init_rumors(rumors);
- if (true_rumor_size < 0L) /* init failed */
- return;
+ if (true_rumor_size < 0L) goto no_rumors; /* init failed */
}
tmpwin = create_nhwindow(NHW_TEXT);
Sprintf(rumor_buf, "T %06ld %s", ftell_rumor_start,
xcrypt(line, xbuf));
putstr(tmpwin, 0, rumor_buf);
+ /* find last true rumor */
+ while (dlb_fgets(line, sizeof line, rumors) &&
+ dlb_ftell(rumors) < true_rumor_end)
+ continue;
+ if ((endp = index(line, '\n')) != 0) *endp = 0;
+ Sprintf(rumor_buf, " %6s %s", "", xcrypt(line, xbuf));
+ putstr(tmpwin, 0, rumor_buf);
rumor_buf[0] = '\0';
(void) dlb_fseek(rumors, false_rumor_start, SEEK_SET);
Sprintf(rumor_buf, "F %06ld %s", ftell_rumor_start,
xcrypt(line, xbuf));
putstr(tmpwin, 0, rumor_buf);
+ /* find last false rumor */
+ while (dlb_fgets(line, sizeof line, rumors) &&
+ dlb_ftell(rumors) < false_rumor_end)
+ continue;
+ if ((endp = index(line, '\n')) != 0) *endp = 0;
+ Sprintf(rumor_buf, " %6s %s", "", xcrypt(line, xbuf));
+ putstr(tmpwin, 0, rumor_buf);
(void) dlb_fclose(rumors);
display_nhwindow(tmpwin, TRUE);
-/* SCCS Id: @(#)makedefs.c 3.5 2005/01/04 */
+/* SCCS Id: @(#)makedefs.c 3.5 2006/05/05 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* Copyright (c) M. Stephenson, 1990, 1991. */
/* Copyright (c) Dean Luick, 1990. */
void
do_rumors()
{
- char infile[60];
- long true_rumor_size;
+ static const char rumors_header[] =
+ "%s%04d,%06ld,%06lx;%04d,%06ld,%06lx;0,0,%06lx\n";
+ char infile[60], tempfile[60];
+ int true_rumor_count, false_rumor_count;
+ long true_rumor_size, false_rumor_size,
+ true_rumor_offset, false_rumor_offset, eof_offset;
+ Sprintf(tempfile, DATA_TEMPLATE, "rumors.tmp");
filename[0]='\0';
#ifdef FILE_PREFIX
- Strcat(filename,file_prefix);
+ Strcat(filename, file_prefix);
#endif
Sprintf(eos(filename), DATA_TEMPLATE, RUMOR_FILE);
- if (!(ofp = fopen(filename,
-#ifdef WIN32
- WRBMODE
-#else
- WRTMODE
-#endif
- ))) {
+ if (!(ofp = fopen(filename, WRTMODE))) {
perror(filename);
exit(EXIT_FAILURE);
}
- Fprintf(ofp,Dont_Edit_Data);
+ if (!(tfp = fopen(tempfile, WRTMODE))) {
+ perror(tempfile);
+ Fclose(ofp);
+ exit(EXIT_FAILURE);
+ }
+
+ true_rumor_count = false_rumor_count = 0;
+ true_rumor_size = false_rumor_size = 0L;
+ true_rumor_offset = false_rumor_offset = eof_offset = 0L;
+
+ /* output a dummy header record; we'll replace it in final output */
+ Fprintf(tfp, rumors_header, Dont_Edit_Data,
+ true_rumor_count, true_rumor_size, true_rumor_offset,
+ false_rumor_count, false_rumor_size, false_rumor_offset,
+ eof_offset);
+ /* record the current position; true rumors will start here */
+ true_rumor_offset = ftell(tfp);
Sprintf(infile, DATA_IN_TEMPLATE, RUMOR_FILE);
Strcat(infile, ".tru");
- if (!(ifp = fopen(infile,
-#ifdef WIN32
- RDBMODE
-#else
- RDTMODE
-#endif
- ))) {
+ if (!(ifp = fopen(infile, RDTMODE))) {
perror(infile);
- Fclose(ofp);
- Unlink(filename); /* kill empty output file */
- exit(EXIT_FAILURE);
+ goto rumors_failure;
}
- /* get size of true rumors file */
-#ifndef VMS
- (void) fseek(ifp, 0L, SEEK_END);
- true_rumor_size = ftell(ifp);
-#else
- /* seek+tell is only valid for stream format files; since rumors.%%%
- might be in record format, count the actual data bytes instead.
- */
- true_rumor_size = 0;
- while (fgets(in_line, sizeof in_line, ifp) != 0)
+ /* copy the true rumors */
+ while (fgets(in_line, sizeof in_line, ifp) != 0) {
+ true_rumor_count++;
true_rumor_size += strlen(in_line); /* includes newline */
-#endif /* VMS */
- Fprintf(ofp,"%06lx\n", true_rumor_size);
- (void) fseek(ifp, 0L, SEEK_SET);
-
- /* copy true rumors */
- while (fgets(in_line, sizeof in_line, ifp) != 0)
- (void) fputs(xcrypt(in_line), ofp);
-
- Fclose(ifp);
+ (void) fputs(xcrypt(in_line), tfp);
+ }
+ /* record the current position; false rumors will start here */
+ false_rumor_offset = ftell(tfp);
+ Fclose(ifp); /* all done with rumors.tru */
+ /* process rumors.fal */
Sprintf(infile, DATA_IN_TEMPLATE, RUMOR_FILE);
Strcat(infile, ".fal");
- if (!(ifp = fopen(infile,
-#ifdef WIN32
- RDBMODE
-#else
- RDTMODE
-#endif
- ))) {
+ if (!(ifp = fopen(infile, RDTMODE))) {
perror(infile);
- Fclose(ofp);
- Unlink(filename); /* kill incomplete output file */
- exit(EXIT_FAILURE);
+ goto rumors_failure;
}
/* copy false rumors */
- while (fgets(in_line, sizeof in_line, ifp) != 0)
- (void) fputs(xcrypt(in_line), ofp);
+ while (fgets(in_line, sizeof in_line, ifp) != 0) {
+ false_rumor_count++;
+ false_rumor_size += strlen(in_line); /* includes newline */
+ (void) fputs(xcrypt(in_line), tfp);
+ }
+ /* record the current position; EOF available for sanity check */
+ eof_offset = ftell(tfp);
+ Fclose(ifp); /* all done with rumors.fal */
- Fclose(ifp);
+ /* get ready to transfer the contents of temp file to output file */
+ Sprintf(in_line, "rewind of \"%s\"", tempfile);
+ if (rewind(tfp) != 0) {
+ perror(in_line);
+ goto rumors_failure;
+ }
+
+ /* output the header record */
+ Fprintf(ofp, rumors_header, Dont_Edit_Data,
+ true_rumor_count, true_rumor_size, true_rumor_offset,
+ false_rumor_count, false_rumor_size, false_rumor_offset,
+ eof_offset);
+ /* skip the temp file's dummy header */
+ if (!fgets(in_line, sizeof in_line, tfp) || /* "Don't Edit" */
+ !fgets(in_line, sizeof in_line, tfp)) { /* count,size,offset */
+ perror(tempfile);
+ goto rumors_failure;
+ }
+ /* copy the rest of the temp file into the final output file */
+ while (fgets(in_line, sizeof in_line, tfp) != 0) {
+ (void) fputs(in_line, ofp);
+ }
+ /* all done; delete temp file */
+ Fclose(tfp);
+ Unlink(tempfile);
Fclose(ofp);
return;
+
+ rumors_failure:
+ Fclose(ofp);
+ Unlink(filename); /* kill empty or incomplete output file */
+ Fclose(tfp);
+ Unlink(tempfile); /* and temporary file */
+ exit(EXIT_FAILURE);
}
/*