2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* Copyright 1992 Hewlett-Packard Co. */
24 static char *version = "$XConsortium: helpcomp.c /main/3 1995/11/08 11:10:34 rswiston $";
34 typedef char LineBuff[BUFSIZ];
35 typedef char FileBuff[BUFSIZ];
36 typedef char *FileName;
38 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
40 static char *prog_name;
41 static char fileNamePrefix[] = "hc";
42 static FileName newHvFileName, newHtFileName,
43 topicFileName, topicZFileName;
46 /* issues an error message, cleans up temp files and exits */
48 ErrorExit(const char *who, const char *how)
50 fprintf(stderr, "%s -> %s: %s\n", prog_name, who, how);
52 if (newHvFileName) unlink(newHvFileName);
53 if (newHtFileName) unlink(newHtFileName);
54 if (topicFileName) unlink(topicFileName);
55 if (topicZFileName) unlink(topicZFileName);
61 /* converts errno into a string and calls ErrorExit() */
63 ErrorIntExit(const char *who, const int how)
65 ErrorExit(who, strerror(how));
69 /* copies a file by name to another file by name */
71 CopyFile(const char *toName, const char *fromName)
77 toFile = open(toName, O_WRONLY|O_CREAT, 0666);
80 ErrorIntExit(toName, errno);
83 fromFile = open(fromName, O_RDONLY);
86 ErrorIntExit(fromName, errno);
89 while ((bytesRead = read(fromFile, fileBuff, sizeof(fileBuff))) > 0)
91 if (write(toFile, fileBuff, bytesRead) != bytesRead)
93 ErrorIntExit(toName, errno);
95 if (bytesRead < sizeof(fileBuff))
112 * Open the old .hv file and a temp file to contain the new .hv file.
114 * Copy lines from the old to the new up to and including the line
115 * "# Topic Locations".
117 * Then, iteratively look for lines containing the string ".filename:",
118 * copying lines from the old .hv to the new until such a line is found.
119 * Copy the found line to the new .hv as well.
121 * If the file name specified after the found string specifies a new
122 * file, finish writing the last open .ht if one exists (i.e., we are
123 * not in the first pass through the loop. Close the previous old .ht
124 * file and the previous new .ht file and move the new one to replace
125 * the old one. Open the recent .ht file specified and open a temp file
126 * to contain the new .ht file.
128 * Read the next line from the old .hv file to get the offset into the
129 * file of the next topic. Subtract the current offset from the next
130 * offset to get the size of the current topic. Read that many bytes
131 * from the old .ht file into a newly created topic file. Close the topic
132 * file and execute compress(1) on it. Attempt to open the topic file
133 * this time with a .Z extension. If possible, the topic was compressed.
134 * If not possible, reopen the topic file as an uncompressed topic.
136 * Append either a 0x0 (compressed) or 0xff (uncompressed) byte to the
137 * new .ht file followed by three bytes holding the size of the topic
138 * determined by fstat'ing the open topic file. The three bytes are
139 * computed using div/mod rather than right shift and mask to avoid byte
142 * Append the contents of the topic file to the new .ht file.
144 * Continue opening, compressing and appending compressed topic files
145 * until a blank line is found in the old .hv file.
147 * When the blank line is found, copy the remaining lines of the old .hv
148 * file to the new .hv file. When finished, move the new .hv file to
149 * replace the old one.
152 main(int argc, char **argv)
155 FILE *oldHvFile, *newHvFile;
156 int oldHtFile, newHtFile, topicZFile;
157 FileName oldHvFileName;
158 LineBuff lineBuff, string1, string2, lastString2, command;
160 int oldOffset, newOffset;
161 int bytesToRead, bytesRead, totalBytes, zFileSize;
162 unsigned char zTmp[4];
163 int doBreak, firstPass, result;
166 pc = strrchr(argv[0], '/');
169 prog_name = malloc(strlen(pc) + 1);
172 fprintf(stderr, "%s: could not copy the program name (no memory)", pc);
175 strcpy(prog_name, pc);
179 fprintf(stderr, "usage: %s <help volume base name>\n", prog_name);
183 oldHvFileName = malloc(strlen(argv[1]) + 3 + 1); /* add ".hv" and null */
186 ErrorExit("malloc", "could not create a temporary file name");
188 strcpy(oldHvFileName, argv[1]);
189 strcat(oldHvFileName, ".hv");
190 oldHvFile = fopen(oldHvFileName, "r");
193 ErrorIntExit(oldHvFileName, errno);
196 newHvFileName = tempnam(NULL, fileNamePrefix);
199 ErrorExit("tempnam", "could not create a temporary file name");
201 newHvFile = fopen(newHvFileName, "w");
204 ErrorIntExit(newHvFileName, errno);
208 if (!fgets(lineBuff, sizeof(lineBuff), oldHvFile))
210 ErrorExit(oldHvFileName, "premature end of input file");
212 fputs(lineBuff, newHvFile);
214 while (strncmp(lineBuff, "# Topic Locations", sizeof("# Topic Locations") - 1));
219 topicFileName = tempnam(NULL, fileNamePrefix);
222 ErrorExit("tempnam", "could not create a temporary file name");
224 strcpy(command, "compress ");
225 strcat(command, topicFileName);
227 topicZFileName = malloc(strlen(topicFileName) + 2 + 1); /* add ".Z" and null */
230 ErrorExit("malloc", "could not create a temporary file name");
232 strcpy(topicZFileName, topicFileName);
233 strcat(topicZFileName, ".Z");
235 newHtFileName = tempnam(NULL, fileNamePrefix);
238 ErrorExit("tempnam", "could not create a temporary file name");
240 newHtFile = open(newHtFileName, O_WRONLY|O_CREAT, 0666);
243 ErrorIntExit(newHtFileName, errno);
251 if (!fgets(lineBuff, sizeof(lineBuff), oldHvFile))
253 ErrorExit(oldHvFileName, "premature end of input file");
255 if (*lineBuff != '\n')
259 fputs(lineBuff, newHvFile);
260 sscanf(lineBuff, "%s %s", string1, string2);
261 pc = strrchr(string1, '.');
262 if (!pc || (strcmp(pc, ".filename:") != 0))
268 strcpy(lastString2, string2);
269 if ((oldHtFile = open(string2, O_RDONLY)) < 0)
271 ErrorIntExit(string2, errno);
280 if (strcmp(string2, lastString2) != 0)
282 topicZFile = open(topicFileName, O_WRONLY|O_CREAT, 0666);
285 ErrorIntExit(topicFileName, errno);
287 while (bytesRead = read(oldHtFile, fileBuff, sizeof(fileBuff)))
289 if (write(topicZFile, fileBuff, bytesRead) != bytesRead)
291 ErrorIntExit(string2, errno);
293 if (bytesRead < sizeof(fileBuff))
300 if ((topicZFile = open(topicZFileName, O_RDONLY)) < 0)
303 topicZFile = open(topicFileName, O_RDONLY);
309 who = (char *) malloc(strlen(topicFileName) +
310 strlen(topicZFileName) +
312 strcpy(who, topicFileName);
314 strcat(who, topicZFileName);
315 ErrorIntExit(who, errno);
318 if (fstat(topicZFile, &statBuf) < 0)
320 ErrorIntExit(topicZFileName, errno);
323 zFileSize = statBuf.st_size;
325 zTmp[3] = zFileSize % 256;
327 zTmp[2] = zFileSize % 256;
329 zTmp[1] = zFileSize % 256;
330 if (write(newHtFile, zTmp, 4) != 4)
332 ErrorIntExit(newHtFileName, errno);
335 while (bytesRead = read(topicZFile, fileBuff, sizeof(fileBuff)))
337 if (write(newHtFile, fileBuff, bytesRead) != bytesRead)
339 ErrorIntExit(string2, errno);
341 if (bytesRead < sizeof(fileBuff))
345 unlink(topicFileName);
346 unlink(topicZFileName);
349 result = CopyFile(lastString2, newHtFileName);
350 unlink(newHtFileName);
352 if (doBreak || result)
355 newHtFile = open(newHtFileName, O_WRONLY|O_CREAT, 0666);
358 ErrorIntExit(newHtFileName, errno);
362 strcpy(lastString2, string2);
364 if ((oldHtFile = open(string2, O_RDONLY)) < 0)
366 ErrorIntExit(string2, errno);
369 if (!fgets(lineBuff, sizeof(lineBuff), oldHvFile))
371 ErrorIntExit(oldHvFileName, errno);
373 sscanf(lineBuff, "%s %d", string1, &newOffset);
374 if (newOffset != oldOffset)
376 bytesToRead = newOffset - oldOffset;
377 topicZFile = open(topicFileName, O_WRONLY|O_CREAT, 0666);
380 ErrorIntExit(topicFileName, errno);
382 while (bytesRead = read(oldHtFile,
384 MIN(bytesToRead, sizeof(fileBuff))))
386 if (write(topicZFile, fileBuff, bytesRead) != bytesRead)
388 ErrorIntExit(topicFileName, errno);
390 if ((bytesToRead -= bytesRead) == 0)
397 if ((topicZFile = open(topicZFileName, O_RDONLY)) < 0)
400 topicZFile = open(topicFileName, O_RDONLY);
406 who = (char *) malloc(strlen(topicFileName) +
407 strlen(topicZFileName) +
409 strcpy(who, topicFileName);
411 strcat(who, topicZFileName);
412 ErrorIntExit(who, errno);
415 if (fstat(topicZFile, &statBuf) < 0)
417 ErrorIntExit(topicZFileName, errno);
420 zFileSize = statBuf.st_size;
422 zTmp[3] = zFileSize % 256;
424 zTmp[2] = zFileSize % 256;
426 zTmp[1] = zFileSize % 256;
427 if (write(newHtFile, zTmp, 4) != 4)
429 ErrorIntExit(newHtFileName, errno);
432 totalBytes += statBuf.st_size + 4;
434 while (bytesRead = read(topicZFile, fileBuff, sizeof(fileBuff)))
436 if (write(newHtFile, fileBuff, bytesRead) != bytesRead)
438 ErrorIntExit(newHtFileName, errno);
440 if (bytesRead < sizeof(fileBuff))
444 unlink(topicFileName);
445 unlink(topicZFileName);
447 fprintf(newHvFile, "%s\t%d\n", string1, totalBytes);
448 oldOffset = newOffset;
451 fputs(lineBuff, newHvFile);
456 ErrorExit(lastString2, "bad file copy");
459 putc('\n', newHvFile);
460 while (!feof(oldHvFile))
462 fgets(lineBuff, sizeof(lineBuff), oldHvFile);
465 fputs(lineBuff, newHvFile);
470 unlink(oldHvFileName);
471 result = CopyFile(oldHvFileName, newHvFileName);
474 ErrorExit(oldHvFileName, "bad file copy");
476 unlink(newHvFileName);