- /*
- * Convert the offsets for the ext_Strings and ext_Names tables,
- * in that order.
- */
- convert_shorts(buf, offsets, strmax);
- TRACE_OUT(("WRITE offsets @%ld", ftell(fp)));
- if (fwrite(buf, 2, strmax, fp) != strmax)
- return(ERR);
-
- /*
- * Write the string table after the offset tables so we do not
- * have to do anything about alignment.
- */
- for (i = 0; i < tp->ext_Strings; i++) {
- if (VALID_STRING(tp->Strings[i+STRCOUNT])) {
- TRACE_OUT(("WRITE ext_Strings[%d]=%s", i, _nc_visbuf(tp->Strings[i+STRCOUNT])));
- if (!WRITE_STRING(tp->Strings[i+STRCOUNT]))
- return(ERR);
- }
- }
+ if (even_boundary(nextfree))
+ return (ERR);
+
+ nextfree = compute_offsets(tp->Strings + STRCOUNT,
+ (size_t) tp->ext_Strings,
+ offsets);
+ TRACE_OUT(("after extended string capabilities, nextfree=%d", nextfree));
+
+ if (tp->ext_Strings >= SIZEOF(offsets))
+ return (ERR);
+
+ nextfree += compute_offsets(tp->ext_Names,
+ (size_t) extcnt,
+ offsets + tp->ext_Strings);
+ TRACE_OUT(("after extended capnames, nextfree=%d", nextfree));
+ strmax = tp->ext_Strings + extcnt;
+
+ /*
+ * Write the extended header
+ */
+ LITTLE_ENDIAN(buf + 0, tp->ext_Booleans);
+ LITTLE_ENDIAN(buf + 2, tp->ext_Numbers);
+ LITTLE_ENDIAN(buf + 4, tp->ext_Strings);
+ LITTLE_ENDIAN(buf + 6, strmax);
+ LITTLE_ENDIAN(buf + 8, nextfree);
+ TRACE_OUT(("WRITE extended-header @%d", *offset));
+ if (Write(buf, 10, 1) != 1)
+ return (ERR);
+
+ TRACE_OUT(("WRITE %d booleans @%d", tp->ext_Booleans, *offset));
+ if (tp->ext_Booleans
+ && Write(tp->Booleans + BOOLCOUNT, sizeof(char),
+ tp->ext_Booleans) != tp->ext_Booleans)
+ return (ERR);
+
+ if (even_boundary(tp->ext_Booleans))
+ return (ERR);
+
+ TRACE_OUT(("WRITE %d numbers @%d", tp->ext_Numbers, *offset));
+ if (tp->ext_Numbers) {
+ convert_numbers(buf, tp->Numbers + NUMCOUNT, (size_t) tp->ext_Numbers);
+ if (Write(buf, 2, tp->ext_Numbers) != tp->ext_Numbers)
+ return (ERR);
+ }
+
+ /*
+ * Convert the offsets for the ext_Strings and ext_Names tables,
+ * in that order.
+ */
+ convert_shorts(buf, offsets, strmax);
+ TRACE_OUT(("WRITE offsets @%d", *offset));
+ if (Write(buf, 2, strmax) != strmax)
+ return (ERR);