/* determines correct huffman code based on current counts in tree, * writes out all to both files overlaying previous values if they existed. */ static void huffman_code (time_t idstamp) { int i; /* current char */ int lasti; int j; /* ascends tree from i to build bit_string */ char bit_string[MAX_BITLEN + 4]; char sprintbuf[128]; char *bitptr; FILE *outstream_huc; FILE *outstream_huf; /* establish the 'literal' node (char #256) count * equal to sum of all chars whose counts are less than threshold. */ if (literal_coding_on) { hctree1[256].count = 0L; for (i = 0; i < 256; i++) if (hctree1[i].count <= literal_threshold) hctree1[256].count += hctree1[i].count; } /* build the Huffman Code tree, and determine root (last_node) */ while (build_tree ()); /* now that we know the total number of tree nodes (last_node), * we are ready to write. * Open both output files and verify they are not write protected. */ if ((outstream_huc = fopen (filename_huc, "w")) == NULL) { fprintf (stderr, catgets(dtsearch_catd, MS_huff, 34, "424 File '%s' failed to open for write. Is it read-only?\n"), filename_huc); exit (2); } if ((outstream_huf = fopen (filename_huf, "w")) == NULL) { fprintf (stderr, catgets(dtsearch_catd, MS_huff, 34, "439 File '%s' failed to open for write. Is it read-only?\n"), filename_huf); exit (2); } /* create the .c decode file (tree as integer array) */ fprintf (outstream_huc, "#include <time.h>\n" "char *hctree_name =\t\"%s\";\n" "time_t hctree_id =\t%ldL;\n" "int hctree_root =\t%d;\n" "static int hctree_array[] = {\n", filename_huc, idstamp, last_node - 257); for (i = 257; i <= last_node; i++) { fprintf (outstream_huc, "\t%4d,\t%4d%c\t/* %3d */\n", hctree1[i].son0 - 257, hctree1[i].son1 - 257, (i == last_node) ? ' ' : ',', /* no comma after last * one */ i - 257); /* comment contains node number */ } fprintf (outstream_huc, "\t};\nint *hctree =\thctree_array;\n"); fclose (outstream_huc); /* write out the tree base (0-256) in sorted order to .huf file */ fprintf (outstream_huf, "%ld\tHCTREE_ID\n", idstamp); for (lasti = -1; (i = next_sorted_node (lasti)) >= 0; lasti = i) { /* * Create huffman code digit string. j ascends tree from i * to build string in reverse order. */ bitptr = bit_string; for (j = i; j != -1; j = hctree1[j].father) *bitptr++ = hctree1[j].bit; *bitptr = '\0'; /* terminate reversed string */ strrev (bit_string); /* reverse the string order */ if (bit_string[1] == 0) strcpy (bit_string, " "); if (strlen (bit_string) < 9) strcat (bit_string, "\t"); /* write out the line for this char */ sprintf (sprintbuf, "%d\t%s\t%ld\t%s\n", i, bit_string + 1, /* hop over LAST_BIT */ hctree1[i].count, char_label (i)); fprintf (outstream_huf, "%s", sprintbuf); } /* end forloop printing out each tree base entry */ fclose (outstream_huf); return; } /* end of function huffman_code */
static void read_in_file(FILE *fd, const char *filename, int show_user_filename) { /** Open the specified file and stream it in to the already opened file descriptor given to us. When we're done output the number of lines and characters we added, if any... **/ FILE *myfd; char exp_fname[SLEN], buffer[SLEN]; int n; int lines = 0, nchars = 0; while (whitespace(*filename)) ++filename; /** expand any shell variables or leading '~' **/ (void) expand_env(exp_fname, filename, sizeof(exp_fname)); if (exp_fname[0] == '\0') { PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmNoFilenameSpecified, "\n\r(No filename specified for file read! Continue.)\n\r")); return; } if ((myfd = fopen(exp_fname,"r")) == NULL) { PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmCouldntReadFile, "\n\r(Couldn't read file '%s'! Continue.)\n\r"), exp_fname); return; } while ((n = mail_gets(buffer, SLEN, myfd))) { if (buffer[n-1] == '\n') lines++; nchars += n; fwrite(buffer, 1, n, fd); } fflush(fd); fclose(myfd); if (lines == 1) PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmAddedLine, "\n\r(Added 1 line [")); else PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmAddedLinePlural, "\n\r(Added %d lines ["), lines); if (nchars == 1) PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmAddedChar, "1 char] ")); else PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmAddedCharPlural, "%d chars] "), nchars); if (show_user_filename) PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmAddedFromFile, "from file %s. Continue.)\n\r"), exp_fname); else PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmAddedToMessage, "to message. Continue.)\n\r")); return; }
/* * The editor used by edit_message() when "builtin" or "none" are selected. * Return 0 if successful, -1 on error. */ static int builtin_editor(const char *filename, SEND_HEADER *shdr) { char linebuf[SLEN]; /* line input buffer */ char wrapbuf[SLEN]; /* wrapped line overflow buffer */ char tmpbuf[SLEN]; /* scratch buffer */ FILE *fp; /* output stream to "filename" */ int rc; /* return code from this procedure */ int is_wrapped; /* wrapped line flag */ int err; /* temp holder for errno */ SIGHAND_TYPE (*oldint)(); /* previous value of SIGINT */ SIGHAND_TYPE (*oldquit)(); /* previous value of SIGQUIT */ SIGHAND_TYPE builtin_interrupt_handler(); /* the built-in editor is not re-entrant! */ assert(!builtin_active); /* initialize return code to failure */ rc = -1; if ((fp = fopen(filename, "r+")) == NULL) { err = errno; sprintf(tmpbuf, catgets(elm_msg_cat, ElmSet, ElmCouldntOpenAppend, "Couldn't open %s for update [%s]."), filename, strerror(err)); PutLine(-1, -1, tmpbuf); dprint(1, (debugfile, "Error encountered trying to open file %s;\n", filename)); dprint(1, (debugfile, "** %s **\n", strerror(err))); return rc; } /* skip past any existing text */ fseek(fp, 0, SEEK_END); /* prompt user, depending upon whether file already has text */ if (fsize(fp) > 0L) strcpy(tmpbuf, catgets(elm_msg_cat, ElmSet, ElmContinueEntering, "\n\rContinue entering message.")); else strcpy(tmpbuf, catgets(elm_msg_cat, ElmSet, ElmEnterMessage, "\n\rEnter message.")); strcat(tmpbuf, catgets(elm_msg_cat, ElmSet, ElmTypeElmCommands, " Type Elm commands on lines by themselves.\n\r")); sprintf(tmpbuf+strlen(tmpbuf), catgets(elm_msg_cat, ElmSet, ElmCommandsInclude, "Commands include: ^D or '.' to end, %cp to list, %c? for help.\n\r\n\r"), escape_char, escape_char); CleartoEOS(); PutLine(-1, -1, tmpbuf); builtin_active = TRUE; builtin_interrupt_count = 0; oldint = signal(SIGINT, builtin_interrupt_handler); oldquit = signal(SIGQUIT, builtin_interrupt_handler); /* return location for interrupts */ while (SETJMP(builtin_jmpbuf) != 0) { if (builtin_interrupt_count == 1) { PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgOneMoreCancel, "(Interrupt. One more to cancel this letter.)\n\r")); } else { PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgCancelled, "(Interrupt. Letter canceled.)\n\r")); goto done; } } for (;;) { /* re-open file if it was closed out on a call to an external editor */ if (fp == NULL) { if ((fp = fopen(filename, "a+")) == NULL) { err = errno; sprintf(tmpbuf, catgets(elm_msg_cat, ElmSet, ElmCouldntOpenAppend, "Couldn't open %s for update [%s]."), filename, strerror(err)); PutLine(-1, -1, tmpbuf); dprint(1, (debugfile, "Error encountered trying to open file %s;\n", filename)); dprint(1, (debugfile, "** %s **\n", strerror(err))); goto done; } PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmPostEdContinue, "(Continue entering message. Type ^D or '.' on a line by itself to end.)\n\r")); } linebuf[0] = '\0'; wrapbuf[0] = '\0'; is_wrapped = 0; more_wrap: if (wrapped_enter(linebuf, wrapbuf, -1, -1, fp, &is_wrapped) != 0) break; if (is_wrapped) { fprintf(fp, "%s\n", linebuf); NewLine(); (void) strcpy(linebuf, wrapbuf); wrapbuf[0] = '\0'; goto more_wrap; } /* reset consecutive interrupt counter */ builtin_interrupt_count = 0; /* a lone "." signals end of text */ if (strcmp(linebuf, ".") == 0) break; /* process line of text */ if (linebuf[0] != escape_char) { fprintf(fp, "%s\n", linebuf); NewLine(); continue; } /* command character was escaped */ if (linebuf[1] == escape_char) { fprintf(fp, "%s\n", linebuf+1); continue; } switch (tolower(linebuf[1])) { case '?': tilde_help(); break; case 't': get_with_expansion("\n\rTo: ", shdr->to, shdr->expanded_to, linebuf); break; case 'b': get_with_expansion("\n\rBcc: ", shdr->bcc, shdr->expanded_bcc, linebuf); break; case 'c': get_with_expansion("\n\rCc: ", shdr->cc, shdr->expanded_cc, linebuf); break; case 's': get_with_expansion("\n\rSubject: ", shdr->subject, (char *)NULL, linebuf); break; case 'h': get_with_expansion("\n\rTo: ", shdr->to, shdr->expanded_to, (char *)NULL); get_with_expansion("Cc: ", shdr->cc, shdr->expanded_cc, (char *)NULL); get_with_expansion("Bcc: ", shdr->bcc, shdr->expanded_bcc, (char *)NULL); get_with_expansion("Subject: ", shdr->subject, (char *)NULL, (char *)NULL); break; case 'r': read_in_file(fp, linebuf+2, 1); break; case 'e': if (e_editor[0] == '\0') { PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmDontKnowEmacs, "\n\r(Don't know where Emacs would be. Continue.)\n\r")); break; } NewLine(); fclose(fp); fp = NULL; (void) edit_message(filename, shdr, e_editor); break; case 'v': NewLine(); fclose(fp); fp = NULL; (void) edit_message(filename, shdr, v_editor); break; case 'o': PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEnterNameEditor, "\n\rPlease enter the name of the editor: ")); if (enter_string(tmpbuf, sizeof(tmpbuf), -1, -1, ESTR_ENTER) < 0 || tmpbuf[0] == '\0') { PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmSimpleContinue, "(Continue.)\n\r")); break; } NewLine(); fclose(fp); fp = NULL; (void) edit_message(filename, shdr, tmpbuf); break; case '<': NewLine(); if (strlen(linebuf) < 3) { PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmUseSpecificCommand, "(You need to use a specific command here. Continue.)\n\r")); break; } sprintf(tmpbuf, "%s%s.%d", temp_dir, temp_edit, getpid()); sprintf(linebuf+strlen(linebuf), " >%s 2>&1", tmpbuf); (void) system_call(linebuf+2, SY_COOKED|SY_ENAB_SIGINT|SY_DUMPSTATE); read_in_file(fp, tmpbuf, 0); (void) unlink(tmpbuf); break; case '!': NewLine(); (void) system_call( (strlen(linebuf) < 3 ? (char *)NULL : linebuf+2), SY_COOKED|SY_USER_SHELL|SY_ENAB_SIGINT|SY_DUMPSTATE); PutLine(LINES, 0, catgets(elm_msg_cat, ElmSet, ElmSimpleContinue, "(Continue.)\n\r")); break; case 'm': /* same as 'f' but with leading prefix added */ case 'f': /* this can be directly translated into a 'readmsg' call with the same params! */ NewLine(); read_in_messages(fp, linebuf+1); break; case 'p': /* print out message so far */ print_message_so_far(fp, shdr); break; default: sprintf(tmpbuf, catgets(elm_msg_cat, ElmSet, ElmDontKnowChar, "\n\r(Don't know what %c%c is. Try %c? for help.)\n\r"), escape_char, linebuf[1], escape_char); PutLine(-1, -1, tmpbuf); break; } } PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEndOfMessage, "\n\r<end-of-message>\n\r\n\r\n\r\n\r")); rc = 0; done: (void) signal(SIGINT, oldint); (void) signal(SIGQUIT, oldquit); if (fp != NULL) fclose(fp); builtin_active = FALSE; return rc; }
int main( int argc, /* Number of arguments */ char *argv[]) /* Argument pointer list */ { extern int optind; char *cwd; int c, i; int errors = 0; /* * Process arguments. */ CustmsgInit(0, NULL); program_name = basename(argv[0]); while ((c = getopt(argc, argv, "c:df:Vv")) != EOF) { switch (c) { case 'c': i = atoi(optarg); if (i < 1 || i > 4) { errors++; fprintf(stderr, "%s: -c %s: invalid copy number\n", program_name, optarg); } CopyMask |= 1<<(i-1); break; case 'd': Damaged = TRUE; break; case 'f': o_fname = optarg; o_fname_specified = TRUE; break; case 'V': case 'v': Verbose = TRUE; break; case '?': default: errors++; } } if (optind == argc) errors++; /* No root_path */ if (errors != 0) { fprintf(stderr, catgets(catfd, SET, 13001, "Usage: %s %s\n"), program_name, "[-c copy_number]... [-f audit_file] [-V] root_path"); return (ES_Args); } if (CopyMask == 0) CopyMask = 0xf; /* If no -c,interested in all copies */ if ((cwd = getcwd(NULL, sizeof (fullpath)-1)) == NULL) { error(1, errno, catgets(catfd, SET, 587, "Cannot get cwd")); } /* * Open the audit output file. Rule is: * If -f not specified, or "-f -" specified, then use stdout * else use filename from -f argument. */ if (o_fname_specified && strcmp(o_fname, "-") != 0) { uid_t uid = getuid(); gid_t gid = getgid(); if ((*o_fname != '/') && (cwd != NULL)) { strncpy(fullpath, cwd, sizeof (fullpath)-1); strncat(fullpath, "/", sizeof (fullpath)-1); } else *fullpath = '\0'; strncat(fullpath, o_fname, sizeof (fullpath)-1); if (NormalizePath(fullpath) == NULL) { error(ES_OutputFile, 0, catgets(catfd, SET, 1423, "Invalid output file path")); } if ((o_st = FOPEN(fullpath, "a")) == NULL) { error(ES_OutputFile, errno, catgets(catfd, SET, 574, "Cannot create %s"), fullpath); } if (chown(fullpath, uid, gid) < 0) { error(0, errno, catgets(catfd, SET, 573, "Cannot chown %s"), fullpath); exit_status = ES_OutputFile; } } else { o_st = stdout; } /* * Check the path to audit. */ if ((*argv[optind] != '/') && (cwd != NULL)) { strncpy(fullpath, cwd, sizeof (fullpath)-1); strncat(fullpath, "/", sizeof (fullpath)-1); } else *fullpath = '\0'; strncat(fullpath, argv[optind], sizeof (fullpath)-1); if (NormalizePath(fullpath) == NULL) error(ES_Path, 0, catgets(catfd, SET, 1425, "Invalid path to audit")); if ((dir_buf = malloc(DIRBUF_SIZE)) == NULL) { error(ES_Malloc, errno, catgets(catfd, SET, 1773, "No memory for directory buffer %d"), DIRBUF_SIZE); } if ((fs_fd = open(fullpath, O_RDONLY)) < 0) { error(ES_Path, errno, catgets(catfd, SET, 613, "Cannot open %s"), fullpath); } /*LINTED pointer cast may result in improper alignment */ getdent_s.dir.ptr = (struct sam_dirent *)dir_buf; /* * Examine the audit path. */ base_name = fullpath; dodir(fullpath); if (o_st != stdout) fclose(o_st); if (Verbose) ListVsns(); if (seg_stat_buf) { free(seg_stat_buf); seg_stat_buf = (struct sam_stat *)NULL; seg_capacity = 0; } return (exit_status); }
/* * Descend through the directories, starting at "name". * Call dofile() for each directory entry. * Save each directory name, and process at the end. */ static void dodir(char *name) { size_t dn_mark, dn_next; char *prev_base; int seg_stat_err; int num_segs; strcpy(base_name, name); /* * Change to the new directory. * Extend the full path. */ if ((dir_fd = open(name, O_RDONLY)) == -1) { error(0, errno, catgets(catfd, SET, 3088, "Cannot open directory %s"), fullpath); if (exit_status < ES_Path) exit_status = ES_Path; return; } getdent_s.offset = 0; dir_buf_count = 0; if (chdir(name) == -1 && chdir(fullpath) == -1) { error(0, errno, catgets(catfd, SET, 3038, "cannot chdir to %s"), fullpath); (void) close(dir_fd); if (exit_status < ES_Path) exit_status = ES_Path; return; } prev_base = base_name; base_name += strlen(name); if (base_name[-1] != '/') { *base_name++ = '/'; } *base_name = '\0'; /* * Mark the directory name stack. */ dn_mark = dn_next = dn_size; while (getdent() > 0) { /* ignore dot and dot-dot */ if (strcmp((const char *) dir->d_name, ".") == 0 || strcmp((const char *) dir->d_name, "..") == 0) continue; /* * check to assure that construction of the full path name does * not exceed the limit before doing the idstat call */ if ((int)(strlen(fullpath) + dir->d_namlen + 1) > MAXPATHLEN) { error(0, errno, catgets(catfd, SET, 268, "%s: Pathname too long"), fullpath); if (exit_status < ES_File) exit_status = ES_File; continue; } strcpy(base_name, (const char *) dir->d_name); idstat.id = dir->d_id; seg_num = 0; if (ioctl(fs_fd, F_IDSTAT, &idstat) < 0) { error(0, errno, catgets(catfd, SET, 1090, "Ioctl call to stat %s (%d, %d) failed."), fullpath, (int)idstat.id.ino, idstat.id.gen); if (exit_status < ES_IDstat) exit_status = ES_IDstat; continue; } if (S_ISREQ(inode.di.mode)) { /* * Try to eliminate removable media files which don't * actually represent space on tape. These are those * for the archiver and stager, and those created by * users for disaster recovery. * For newly created filesystems, those for the * archiver and stager will have parent inode * SAM_ARCH_INO (5) and SAM_STAGE_INO (7) respectively. * For legacy file systems we don't have a clue. * Those created by users for reading * (disaster recovery) which haven't been referenced * will have size of MAXOFFSET_T, so throw these out too * (in CheckRmStatus() ). */ if ((inode.di.parent_id.ino != SAM_ARCH_INO) && (inode.di.parent_id.ino != SAM_STAGE_INO)) { CheckRmStatus(); } } else { CheckArchiveStatus(); } if (S_ISSEGI(&inode.di)) { /* * Inode is an index inode, perform archive_audit of * any archive copies of the file's data segments. */ seg_stat_err = seg_stat_path(&num_segs); if (seg_stat_err) { continue; } for (seg_num = 1; seg_num <= num_segs; seg_num++) { idstat.id.ino = (sam_ino_t)seg_stat_buf[seg_num - 1].st_ino; idstat.id.gen = (int32_t)seg_stat_buf[seg_num - 1].gen; if (ioctl(fs_fd, F_IDSTAT, &idstat) < 0) { error(0, errno, catgets(catfd, SET, 1091, "Ioctl call to stat %s, " "segment %d (%d, %d) failed."), fullpath, seg_num, (int)idstat.id.ino, idstat.id.gen); if (exit_status < ES_IDstat) exit_status = ES_IDstat; continue; } CheckArchiveStatus(); } } if (S_ISDIR(inode.di.mode)) adddir((char *)dir->d_name); } if (close(dir_fd) < 0) { error(0, errno, catgets(catfd, SET, 3040, "cannot close directory %s"), fullpath); if (exit_status < ES_CloseFile) exit_status = ES_CloseFile; } /* * Process all the directories found. */ while (dn_next < dn_size) { char *name; name = &dir_names[dn_next]; dn_next += strlen(name) + 1; dodir(name); } dn_size = dn_mark; base_name = prev_base; *base_name = '\0'; if (chdir("..") < 0 && chdir(fullpath) < 0) { error(0, errno, catgets(catfd, SET, 572, "cannot chdir to \"..\" %s"), fullpath); if (exit_status < ES_Path) exit_status = ES_Path; } }
int /* fd if successful, -1 if error */ get_blk_device( struct sam_fs_part *fsp, int oflags, int maxdevretry) { int fd; int retrycnt = 0; struct dk_cinfo dkcinfo; struct vtoc vtoc; char *devrname; if (check_mnttab(fsp->pt_name)) { error(0, 0, catgets(catfd, SET, 13422, "device %s is mounted."), fsp->pt_name); return (-1); } if ((devrname = getfullrawname(fsp->pt_name)) == NULL) { error(0, 0, catgets(catfd, SET, 1606, "malloc: %s"), "getfullrawname"); return (-1); } if (*devrname == '\0') { error(0, errno, "%s", fsp->pt_name); error(0, 0, catgets(catfd, SET, 1998, "Raw device not found for eq (%d)"), fsp->pt_eq); free(devrname); return (-1); } /* * Oracle RAC (oban) devices under SunCluster initialize at the * same time as QFS filesystems are mounted. We loop waiting * for the devices to become available (maximum of maxdevretry * tries). */ while ((fd = open(devrname, oflags)) < 0) { if ((retrycnt >= maxdevretry) || ((strncmp(devrname, "/dev/md/", 8) != 0))) { error(0, errno, "%s", devrname); error(0, 0, catgets(catfd, SET, 1856, "Open failed on (%s), retries=%d"), devrname, retrycnt); free(devrname); return (-1); } retrycnt++; sleep(2); } if (retrycnt > 0) { printf("%s: %d retries on %s (max=%d).\n", program_name, retrycnt, devrname, maxdevretry); } if (ioctl(fd, DKIOCINFO, &dkcinfo) < 0) { error(0, errno, "%s", devrname); error(0, 0, catgets(catfd, SET, 1443, "Ioctl(DKIOCINFO) failed on (%s)"), devrname); free(devrname); return (-1); } if (ioctl(fd, DKIOCGVTOC, &vtoc) >= 0) { /* * Size of partition is returned in units of 512 * byte sectors. */ fsp->pt_size = (unsigned long) vtoc.v_part[dkcinfo.dki_partition].p_size; if (fsp->pt_size == 0) { error(0, 0, catgets(catfd, SET, 1909, "Partition %d is undefined on (%s)"), dkcinfo.dki_partition, devrname); free(devrname); return (-1); } } else if (is_efi_present()) { int part; int saved_errno; struct dk_gpt *efi_vtoc; saved_errno = errno; if ((part = call_efi_alloc_and_read(fd, &efi_vtoc)) >= 0) { fsp->pt_size = efi_vtoc->efi_parts[part].p_size; call_efi_free(efi_vtoc); if (fsp->pt_size == 0) { error(0, 0, catgets(catfd, SET, 1909, "Partition %d is undefined on (%s)"), part, devrname); free(devrname); return (-1); } } else { error(0, saved_errno, "%s", devrname); error(0, 0, catgets(catfd, SET, 13030, "Could not read VTOC or EFI label on %s: %d"), devrname, part); free(devrname); return (-1); } } else { error(0, errno, "%s", devrname); error(0, 0, catgets(catfd, SET, 1442, "Ioctl(DKIOCGVTOC) failed on (%s)"), devrname); free(devrname); return (-1); } free(devrname); return (fd); }
int main (int argc, char **argv) { char *s, *prompt; char drive[_MAX_DRIVE]; /* for _splitpath, _makepath */ char dir[_MAX_DIR]; /* for _splitpath, _makepath */ char file[_MAX_FNAME]; /* for _splitpath, _makepath */ char ext[_MAX_EXT]; /* for _splitpath, _makepath */ char fullpath[_MAX_PATH]; /* the full path after _makepath */ int i; int next; /* return value of more() function */ int done; /* flag for findfirst, findnext */ int exitval; /* exit value */ int pfile; /* file handle */ struct ffblk ffblk; /* findfirst, findnext block */ nl_catd cat; /* message catalog */ int stdinhandle; int someFileFound; int more_prompt_needed = 0; GetScreenSize(); /* Open the message catalog */ cat = catopen ("more", 0); prompt = catgets (cat, 2, 0, "More"); /* Evaluate the files on the command line */ /* we want to use DOS to get characters from STDIN. STDIN MAY have been redirected, which is not acceptable to more however, we want to be able to work with CTTY COM1 so using the BIOS isn't an option as well. so we duplicate STDIN to a new handle, and duplicate STDERR (possibly COM1) to STDIN then STDIN is available for character input again */ stdinhandle = dos_dup(0); if (stdinhandle < 0) { printf("??\n"); exit(1); } dos_close(0); if (dos_dup2(2,0)) { printf("???\n"); exit(1); } for (i = 1; i < argc; i++) { /* Check if we are asking for help */ if (argv[i][0] != '/') { continue; } /* This is a flag character */ /* Add any code here that deals with special flag chars */ switch (argv[i][1]) { case '?': case 'H': case 'h': /* print usage and quit */ s = catgets (cat, 0, 0, "Display the contents of a text file one screen at a time"); printf ("MORE: %s\n", s); usage (cat); catclose (cat); exit (0); break; case 't': case 'T': if ( argv[i][2] < '1' || argv[i][2] > '9') { printf("MORE:%s\n", catgets(cat,1,3,"option /Tabs must be /T1..9 (default 4)\n")); exit(1); } TABSIZE = argv[i][2] - '0'; break; default: /* Not a recognized option */ s = catgets (cat, 1, 0, "Not a recognized option"); printf ("MORE: %s: %s\n", argv[i], s); usage (cat); catclose (cat); exit (1); break; } /* switch */ } someFileFound = 0; for (i = 1; i < argc; i++) { /* Check if we are asking for help */ if (argv[i][0] == '/') /* arguments have been handled already */ { continue; } someFileFound = 1; /* Assume a file. Open it and display it. */ /* Note that findfirst, findnext only return the base file name in ff_name, and not the path. The search still works with a path, but you don't get it back. So we have to preserve the full path to the file using _splitpath and _makepath. */ _splitpath (argv[i], drive, dir, file, ext); done = findfirst (argv[i], &ffblk, 0); if (done) { /* We were not able to find a file. Display a message and set the exit value. */ s = catgets (cat, 1, 1, "No such file"); printf ( "MORE: %s: %s\n", argv[i], s); exit(1); } while (!done) { /* We have found a file, so open it and display it. Set the exit value to 'successful' */ if (more_prompt_needed) { next = prompt_for_more(fullpath); /* Find next file */ /* but only if user did not press 'Q' during more() */ if (next == 0) { exit(0); } } _makepath (fullpath, drive, dir, ffblk.ff_name, ""); pfile = dos_open (fullpath, 0); if (pfile < 0) { s = catgets (cat, 1, 2, "Cannot open file"); printf ( "MORE: %s: %s\n", ffblk.ff_name, s); exit(1); } more_prompt_needed = 1; more (pfile, ffblk.ff_name, prompt); dos_close (pfile); exitval = 0; done = findnext (&ffblk); } /* while */ } /* for */ if (!someFileFound) /* nothing done - use STDIN */ { /* Process the standard input. Return from more() is not used. */ s = catgets (cat, 2, 1, "<STDIN>"); more (stdinhandle, s, prompt); exitval = 0; } /* Done */ catclose (cat); return exitval; }
inst_t disk_install(const char *datfile, const char *descfile, char *fromdir, char *destdir) { char lsmfile[MAXPATH]; /* Linux software map file */ char *s; int dat_size = 30; /* malloc size of the dat array */ int dat_count; /* size of the dat array */ int ret; int ch; int i; int pkg_yesToAll = 0; /* Assume default yes to all = not specified */ dat_t *dat_ary; /* the DAT array */ inst_t this; /* return: no. of errors,warnings */ /* Initialize variables */ this.errors = 0; this.warnings = 0; /* Read dat file */ dat_ary = malloc (sizeof (dat_t) * dat_size); if (dat_ary == NULL) { s = catgets (cat, SET_ERRORS, MSG_ERROR, MSG_ERROR_STR); fprintf (stderr, s); log("<error msg=\"%s\" />\n", s); s = catgets (cat, SET_ERRORS, MSG_ERRALLOCMEMFDF, MSG_ERRALLOCMEMFDF_STR); fprintf (stderr, s); log("<error msg=\"%s\" />\n", s); pause(); return (this); } dat_count = dat_read (datfile, dat_ary, dat_size); if (dat_count < 1) { s = catgets (cat, SET_ERRORS, MSG_ERROR, MSG_ERROR_STR); fprintf (stderr, s); log("<error msg=\"%s\" />\n", s); s = catgets (cat, SET_ERRORS, MSG_ERREMPTYFLOPPYDATAFILE, MSG_ERREMPTYFLOPPYDATAFILE_STR); fprintf (stderr, s); log("<error msg=\"%s\" />\n", s); pause(); free (dat_ary); return (this); } /* Run the install */ for (i = 0; i < dat_count; i++) { /* Print the screen and progress bargraph */ repaint_empty(); box (14, 16, 66, 18); gotoxy (15, 17); bargraph (i, dat_count, 50 /* width */); /* Print the package name */ gotoxy (2, 5); s = catgets (cat, SET_PKG_GENERAL, MSG_PACKAGE, MSG_PACKAGE_STR); cputs (s); cputs (dat_ary[i].name); /* Show the package description */ /* Generate the lsmfile name */ fnmerge (lsmfile, "", fromdir, dat_ary[i].name, "LSM"); if (isfile (lsmfile)) { lsm_description (8, 2, 10, lsmfile); } else { /* no lsm file. try it again with a plain txt file */ fnmerge (lsmfile, "", fromdir, dat_ary[i].name, ""); if (isfile (lsmfile)) { gotoxy (2, 8); cat_file (lsmfile, 10 /* no. lines */); } } /* Find out which ones the user wants to install */ gotoxy (2, 25); switch (dat_ary[i].rank) { case 'n': case 'N': /* Do not install */ log("<package name=\"%s\" choice=\"n\" />\n", dat_ary[i].name); s = catgets (cat, SET_PKG_NEED, MSG_SKIPPED, MSG_SKIPPED_STR); cputs (s); break; case 'y': case 'Y': /* Always install */ log("<package name=\"%s\" choice=\"y\" />\n", dat_ary[i].name); s = catgets (cat, SET_PKG_NEED, MSG_REQUIRED, MSG_REQUIRED_STR); cputs (s); ret = unzip_file (dat_ary[i].name, fromdir, destdir); reregisterSIGINTHandler(); /* unzip installs its own SIGINT handler */ if (ret != 0) { /* Print an error message */ s = catgets (cat, SET_PKG_GENERAL, MSG_ERRREQPKG, MSG_ERRREQPKG_STR); cputs (s); log("<error msg=\"%s\" />\n", s); /* Return an error */ this.errors++; /* Does the user want to continue anyway? */ s = catgets (cat, SET_PROMPT_YN, MSG_CONTINSTDISK, MSG_CONTINSTDISK_STR); ch = select_yn(s, yes, no, NULL, NULL); if (ch) { log("<abort msg=\"User choose not to continue after error.\" />\n"); return (this); } } break; default: /* Optional */ s = catgets (cat, SET_PKG_NEED, MSG_OPTIONAL, MSG_OPTIONAL_STR); cputs (s); /* Ask the user if you want to install it */ s = catgets (cat, SET_PROMPT_YN, MSG_INSTALLPKG, MSG_INSTALLPKG_STR); if (!pkg_yesToAll) { ch = select_yn (s, yes, no, catgets (cat, SET_PROMPT_YN, MSG_YESTOALL, MSG_YESTOALL_STR), NULL); if (ch == 2) pkg_yesToAll = 1; } if (pkg_yesToAll || ch==0) /* Yes or YesToAll */ { log("<package name=\"%s\" choice=\"y\" />\n", dat_ary[i].name); ret = unzip_file (dat_ary[i].name, fromdir, destdir); reregisterSIGINTHandler(); /* unzip installs its own SIGINT handler */ if (ret != 0) { /* Print a warning message */ gotoxy (2, 23); s = catgets (cat, SET_PKG_GENERAL, MSG_WARNOPTPKG, MSG_WARNOPTPKG_STR); cputs (s); log("<warning msg=\"%s\" />\n", s); pause(); this.warnings++; } } else /* user selected no */ log("<package name=\"%s\" choice=\"n\" />\n", dat_ary[i].name); break; } /* switch */ } /* for */ /* Print the screen and 100% complete progress bargraph */ repaint_empty(); box (14, 16, 66, 18); gotoxy (15, 17); bargraph (1, 1, 50 /* width */); /* Free memory for this disk */ free (dat_ary); return (this); }
inst_t set_install (const char *diskset, char *fromdir, char *destdir) { /* Variables */ char endfile[MAXPATH]; /* marks end of series */ char descfile[MAXPATH]; /* description file */ char datfile[MAXPATH]; /* current DAT file */ char ext[MAXPATH]; /* file extension */ char *s; int disknum = 0; /* current disk number */ int ch; inst_t ret; /* return: no. of errors,warnings */ inst_t this; /* no. of errors,warnings */ /* Create the filenames */ fnmerge (endfile, "", fromdir, diskset, "END"); /* fnmerge (descfile, "", fromdir, diskset, "TXT"); */ fnmerge (descfile, "", fromdir, diskset, ""); /* Print the name of the series we are working on */ repaint_empty(); s = catgets (cat, SET_PKG_GENERAL, MSG_INSTSERIES, MSG_INSTSERIES_STR); gotoxy (2, 3); cputs (s); cputs (diskset); log("<diskset name=\"%s\" >\n", diskset); /* Install while we have disks to work from. Since we will reach an exit condition within the loop, we use an infinite loop here. */ ret.errors = 0; ret.warnings = 0; while (1) { repaint_empty(); /* First check that the datfile exists. If it doesn't, check if the endfile was found. */ sprintf (ext, "%d", ++disknum); fnmerge (datfile, "", fromdir, diskset, ext); if (!isfile (datfile)) { /* Does the endfile exist? */ if (isfile (endfile)) { s = catgets (cat, SET_PKG_GENERAL, MSG_INSTSERIESDONE, MSG_INSTSERIESDONE_STR); gotoxy (2, 10); cputs (s); s = catgets (cat, SET_PKG_GENERAL, MSG_NEXTSERIESDISK, MSG_NEXTSERIESDISK_STR); gotoxy (2, 15); cputs (s); s = catgets (cat, SET_PKG_GENERAL, MSG_NEXTSERIESDISK2, MSG_NEXTSERIESDISK2_STR); gotoxy (2, 16); cputs (s); log("</diskset>\n\n"); pause(); return (ret); } /* The endfile was not found, so we know there is at least one more disk left to do. Keep asking the user to insert the next disk. */ do { /* If this is the 1st disk in the series, then instead of assuming wrong disk prompt for them to insert the disk. */ if (disknum == 1) { s = catgets (cat, SET_PKG_GENERAL, MSG_INSERT1STDISK, MSG_INSERT1STDISK_STR); gotoxy (2, 10); cprintf(s, diskset); } else { s = catgets (cat, SET_PKG_GENERAL, MSG_MISSINGDATAFILE, MSG_MISSINGDATAFILE_STR); gotoxy (2, 10); cputs (s); gotoxy (2, 11); cputs (datfile); s = catgets (cat, SET_PKG_GENERAL, MSG_WRONGFLOPPY, MSG_WRONGFLOPPY_STR); gotoxy (2, 15); cputs (s); s = catgets (cat, SET_PKG_GENERAL, MSG_STILLWRONGFLOPPY, MSG_STILLWRONGFLOPPY_STR); gotoxy (2, 16); cputs (s); } s = catgets (cat, SET_PROMPT_YN, MSG_CONTINSTDISK, MSG_CONTINSTDISK_STR); ch = select_yn (s, yes, no, NULL, NULL); if (ch) { /* user has decided to quit this series */ log("</diskset>\n\n"); return (ret); } } while (!isfile (datfile)); } /* if no datfile */ /* Install files from this disk */ log("<disk name=\"%s\" number=\"%i\" >\n", diskset, disknum); this = disk_install (datfile, descfile, fromdir, destdir); log("</disk>\n"); ret.errors += this.errors; ret.warnings += this.warnings; } /* while (1) */ }
/* * Fully cleanup the screen, leaving no @ lines except at end when * line after last won't completely fit. The routine vsync is * more conservative and much less work on dumb terminals. */ void vredraw(register int p) { register int l; register line *tp; char temp[LBSIZE]; bool anydl = 0; short oldhold = hold; #ifdef ADEBUG if (trace) tfixnl(), fprintf(trace, "vredraw(%d)\n", p), tvliny(); #endif if (holdupd) { holdupd = 3; return; } if (state == HARDOPEN || splitw) return; if (p < 0 /* || p > WECHO */) error(catgets(catd, 1, 221, "Internal error: vredraw")); /* * Trim the ragged edges (lines which are off the screen but * not yet logically discarded), save the current line, and * search for first logical line affected by the redraw. */ vscrap(); CP(temp, linebuf); l = 0; tp = dot - vcline; if (vcnt == 0) LINE(0) = WTOP; while (l < vcnt && LINE(l) < p) l++, tp++; /* * We hold off echo area clearing during the redraw in deference * to a final clear of the echo area at the end if appropriate. */ heldech = 0; hold |= HOLDECH; for (; l < vcnt && Peekkey != ATTN; l++) { if (l == vcline) strcLIN(temp); else getline(*tp); /* * Delete junk between displayed lines. */ if (LINE(l) != LINE(l + 1) && LINE(l) != p) { if (anydl == 0 && DB && CD) { hold = oldhold; vclrech(0); anydl = 1; hold |= HOLDECH; heldech = 0; } vdellin(p, LINE(l) - p, l); } /* * If line image is not know to be up to date, then * redisplay it; else just skip onward. */ LINE(l) = p; if (FLAGS(l) & VDIRT) { DEPTH(l) = vdepth(); if (l != vcline && p + DEPTH(l) - 1 > WBOT) { vscrap(); break; } FLAGS(l) &= ~VDIRT; vreopen(p, lineno(tp), l); p = LINE(l) + DEPTH(l); } else p += DEPTH(l); tp++; } /* * That takes care of lines which were already partially displayed. * Now try to fill the rest of the screen with text. */ if (state == VISUAL && p <= WBOT) { int ovcline = vcline; vcline = l; for (; tp <= dol && Peekkey != ATTN; tp++) { getline(*tp); if (p + vdepth() - 1 > WBOT) break; vopen(tp, p); p += DEPTH(vcline); vcline++; } vcline = ovcline; } /* * Thats all the text we can get on. * Now rest of lines (if any) get either a ~ if they * are past end of file, or an @ if the next line won't fit. */ for (; p <= WBOT && Peekkey != ATTN; p++) vclrlin(p, tp); strcLIN(temp); hold = oldhold; if (heldech) vclrech(0); #ifdef ADEBUG if (trace) tvliny(); #endif }
int strerror_r (int errnum, char *buf, size_t buflen) #undef strerror_r { /* Filter this out now, so that rest of this replacement knows that there is room for a non-empty message and trailing NUL. */ if (buflen <= 1) { if (buflen) *buf = '\0'; return ERANGE; } *buf = '\0'; /* Check for gnulib overrides. */ { char const *msg = strerror_override (errnum); if (msg) return safe_copy (buf, buflen, msg); } { int ret; int saved_errno = errno; #if USE_XPG_STRERROR_R { extern int __xpg_strerror_r (int errnum, char *buf, size_t buflen); ret = __xpg_strerror_r (errnum, buf, buflen); if (ret < 0) ret = errno; if (!*buf) { /* glibc 2.13 would not touch buf on err, so we have to fall back to GNU strerror_r which always returns a thread-safe untruncated string to (partially) copy into our buf. */ safe_copy (buf, buflen, strerror_r (errnum, buf, buflen)); } } #elif USE_SYSTEM_STRERROR_R if (buflen > INT_MAX) buflen = INT_MAX; # ifdef __hpux /* On HP-UX 11.31, strerror_r always fails when buflen < 80; it also fails to change buf on EINVAL. */ { char stackbuf[80]; if (buflen < sizeof stackbuf) { ret = strerror_r (errnum, stackbuf, sizeof stackbuf); if (ret == 0) ret = safe_copy (buf, buflen, stackbuf); } else ret = strerror_r (errnum, buf, buflen); } # else ret = strerror_r (errnum, buf, buflen); /* Some old implementations may return (-1, EINVAL) instead of EINVAL. */ if (ret < 0) ret = errno; # endif # ifdef _AIX /* AIX returns 0 rather than ERANGE when truncating strings; try again until we are sure we got the entire string. */ if (!ret && strlen (buf) == buflen - 1) { char stackbuf[STACKBUF_LEN]; size_t len; strerror_r (errnum, stackbuf, sizeof stackbuf); len = strlen (stackbuf); /* STACKBUF_LEN should have been large enough. */ if (len + 1 == sizeof stackbuf) abort (); if (buflen <= len) ret = ERANGE; } # else /* Solaris 10 does not populate buf on ERANGE. OpenBSD 4.7 truncates early on ERANGE rather than return a partial integer. We prefer the maximal string. We set buf[0] earlier, and we know of no implementation that modifies buf to be an unterminated string, so this strlen should be portable in practice (rather than pulling in a safer strnlen). */ if (ret == ERANGE && strlen (buf) < buflen - 1) { char stackbuf[STACKBUF_LEN]; /* STACKBUF_LEN should have been large enough. */ if (strerror_r (errnum, stackbuf, sizeof stackbuf) == ERANGE) abort (); safe_copy (buf, buflen, stackbuf); } # endif #else /* USE_SYSTEM_STRERROR */ /* Try to do what strerror (errnum) does, but without clobbering the buffer used by strerror(). */ # if defined __NetBSD__ || defined __hpux || ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __CYGWIN__ /* NetBSD, HP-UX, native Win32, Cygwin */ /* NetBSD: sys_nerr, sys_errlist are declared through _NETBSD_SOURCE and <errno.h> above. HP-UX: sys_nerr, sys_errlist are declared explicitly above. native Win32: sys_nerr, sys_errlist are declared in <stdlib.h>. Cygwin: sys_nerr, sys_errlist are declared in <errno.h>. */ if (errnum >= 0 && errnum < sys_nerr) { # if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux) # if defined __NetBSD__ nl_catd catd = catopen ("libc", NL_CAT_LOCALE); const char *errmsg = (catd != (nl_catd)-1 ? catgets (catd, 1, errnum, sys_errlist[errnum]) : sys_errlist[errnum]); # endif # if defined __hpux nl_catd catd = catopen ("perror", NL_CAT_LOCALE); const char *errmsg = (catd != (nl_catd)-1 ? catgets (catd, 1, 1 + errnum, sys_errlist[errnum]) : sys_errlist[errnum]); # endif # else const char *errmsg = sys_errlist[errnum]; # endif if (errmsg == NULL || *errmsg == '\0') ret = EINVAL; else ret = safe_copy (buf, buflen, errmsg); # if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux) if (catd != (nl_catd)-1) catclose (catd); # endif } else ret = EINVAL; # elif defined __sgi || (defined __sun && !defined _LP64) /* IRIX, Solaris <= 9 32-bit */ /* For a valid error number, the system's strerror() function returns a pointer to a not copied string, not to a buffer. */ if (errnum >= 0 && errnum < sys_nerr) { char *errmsg = strerror (errnum); if (errmsg == NULL || *errmsg == '\0') ret = EINVAL; else ret = safe_copy (buf, buflen, errmsg); } else ret = EINVAL; # else gl_lock_lock (strerror_lock); { char *errmsg = strerror (errnum); /* For invalid error numbers, strerror() on - IRIX 6.5 returns NULL, - HP-UX 11 returns an empty string. */ if (errmsg == NULL || *errmsg == '\0') ret = EINVAL; else ret = safe_copy (buf, buflen, errmsg); } gl_lock_unlock (strerror_lock); # endif #endif if (ret == EINVAL && !*buf) snprintf (buf, buflen, "Unknown error %d", errnum); errno = saved_errno; return ret; } }
/* * Repaint the screen, with cursor at curs, aftern an arbitrary change. * Handle notification on large changes. */ void vrepaint(char *curs) { wdot = NOLINE; /* * In open want to notify first. */ noteit(0); vscrap(); /* * Deal with a totally useless display. */ if (vcnt == 0 || vcline < 0 || vcline > vcnt || holdupd && state != VISUAL) { register line *odol = dol; vcnt = 0; if (holdupd) if (state == VISUAL) ignore(peekkey()); else vup1(); holdupd = 0; if (odol == zero) fixzero(); vcontext(dot, '.'); noteit(1); if (noteit(1) == 0 && odol == zero) { CATCH error(catgets(catd, 1, 220, "No lines in buffer")); ENDCATCH linebuf[0] = 0; splitw = 0; } vnline(curs); return; } /* * Have some useful displayed text; refresh it. */ getDOT(); /* * This is for boundary conditions in open mode. */ if (FLAGS(0) & VDIRT) vsync(WTOP); /* * If the current line is after the last displayed line * or the bottom of the screen, then special effort is needed * to get it on the screen. We first try a redraw at the * last line on the screen, hoping it will fill in where @ * lines are now. If this doesn't work, then roll it onto * the screen. */ if (vcline >= vcnt || LINE(vcline) > WBOT) { short oldhold = hold; hold |= HOLDAT, vredraw(LASTLINE), hold = oldhold; if (vcline >= vcnt) { register int i = vcline - vcnt + 1; dot -= i; vcline -= i; vroll(i); } else vsyncCL(); } else vsync(vcline > 0 ? LINE(vcline - 1) : WTOP); /* * Notification on large change for visual * has to be done last or we may lose * the echo area with redisplay. */ noteit(1); /* * Finally. Move the cursor onto the current line. */ vnline(curs); }
int main (int argc, char *argv[]) { FILE *instream; struct stat fstat_input; long bytes_in = 0L; int mychar; time_t now, start_stamp; setlocale (LC_ALL, ""); dtsearch_catd = catopen (FNAME_DTSRCAT, 0); printf (catgets(dtsearch_catd, MS_huff, 40, "HUFFCODE Version %s\n"), AUSAPI_VERSION); /* validate user's command line arguments */ user_args_processor (argc, argv); /* initialize tree table, using the table file if it exists */ init_treebase (); if (total_count == 0L) printf ("%s", catgets(dtsearch_catd, MS_huff, 41, "Huffman Code Tables will be newly created.\n")); else printf (catgets(dtsearch_catd, MS_huff, 42, "Table '%s' already contains %ld Kbytes from previous runs.\n"), filename_huf, total_count / 1000L); if (!input_file_specified && no_huffcode_file) { fprintf (stderr, catgets(dtsearch_catd, MS_huff, 43, "645 Input file not specified and '%s' table file\n" " doesn't exist--nothing to do!\n"), filename_huf); print_usage (); exit (2); } /* read the input file and count its bytes */ if (input_file_specified) { if ((instream = fopen (filename_input, "rb")) == NULL) { BAD_INPUT_FILE: fprintf (stderr, catgets(dtsearch_catd, MS_huff, 44, "Could not open input file '%s' or access status: %s\n"), filename_input, strerror (errno)); exit (2); } if (fstat (fileno (instream), &fstat_input) == -1) goto BAD_INPUT_FILE; printf (catgets(dtsearch_catd, MS_huff, 45, "Input file '%s' contains about %ld Kbytes.\n"), filename_input, fstat_input.st_size / 1000L); time (&start_stamp); while ((mychar = getc (instream)) != EOF) { hctree1[mychar].count++; total_count++; /* echo progress to user every so often */ if (!(++bytes_in % 10000L)) printf (catgets(dtsearch_catd, MS_huff, 46, "\r%ld%% done. %2ld Kbytes read. " "Estimate %3ld seconds to completion. "), (bytes_in * 100L) / fstat_input.st_size, bytes_in / 1000L, (fstat_input.st_size - bytes_in) * (time (NULL) - start_stamp) / bytes_in); } /* end read loop for each char in input file */ putchar ('\n'); fclose (instream); } /* endif that processes input file */ /* build huffman code tree, write out files */ time (&now); /* this will be the official tree id time * stamp */ printf (catgets(dtsearch_catd, MS_huff, 47, "Identifying timestamp will be '%ld'.\n" "%s Huffman Code Tables in '%s' and '%s'..."), now, (no_huffcode_file) ? catgets(dtsearch_catd, MS_huff, 48, "Creating") : catgets(dtsearch_catd, MS_huff, 49, "Rebuilding"), filename_huf, filename_huc); huffman_code (now); putchar ('\n'); return 0; } /* end of function main */
/* handles command line arguments for 'main' */ static void user_args_processor (int argc, char **argv) { char *argptr; int OK_to_overwrite = FALSE; FILE *stream; if (argc <= 1) { /* user just wants to see usage msg */ print_usage (); exit (1); } /* each pass grabs new parm of "-xxx" format */ while (--argc > 0 && (*++argv)[0] == '-') { argptr = argv[0]; argptr[1] = tolower (argptr[1]); switch (argptr[1]) { case 'l': /* literal threshold */ if (argptr[2] == 0) goto BADARG; else if (argptr[2] == '-') literal_coding_on = FALSE; else literal_threshold = atoi (argptr + 2); break; case 'o': /* OK_to_overwrite .c file if it already * exists */ OK_to_overwrite = TRUE; break; case 'v': /* verbose mode = debug switch */ debug_switch = TRUE; break; BADARG: default: fprintf (stderr, catgets(dtsearch_catd, MS_huff, 36, "'%s' is invalid argument.\n"), argptr); print_usage (); exit (2); /* ABORT program */ } /* endswitch */ } /* endwhile for cmd line '-'processing */ /* test for required tree file name */ if (argc <= 0) { fprintf (stderr, "%s", catgets(dtsearch_catd, MS_huff, 37, "576 Missing Huffman Code file names prefix.\n")); print_usage (); exit (2); } /* create 2 output file names from passed argument */ strncpy (filename_huf, argv[0], _POSIX_PATH_MAX); filename_huf[_POSIX_PATH_MAX - 6] = 0; strcat (filename_huf, EXT_HUFFCODE); strncpy (filename_huc, argv[0], _POSIX_PATH_MAX); filename_huc[_POSIX_PATH_MAX - 6] = 0; strcat (filename_huc, EXT_HDECODE); /* Since the decode file is a C source code file (.c extension), * we want to be sure not to erase somebody's source program. * So if the .c file already exists, and the user didn't specify * overwrite in a command line argument, ask him now if it's OK to * blow away the old file. */ if (!OK_to_overwrite) if ((stream = fopen (filename_huc, "r")) != NULL) { fclose (stream); printf (catgets(dtsearch_catd, MS_huff, 38, "Decode file '%s' already exists. " "Is it OK to overwrite it? [y/n] "), filename_huc); if (toupper (getchar ()) != 'Y') exit (2); } /* test for optional input file name */ if (--argc <= 0) input_file_specified = FALSE; else { input_file_specified = TRUE; strncpy (filename_input, argv[1], _POSIX_PATH_MAX); filename_input[_POSIX_PATH_MAX - 1] = 0; } return; } /* end of function user_args_processor */
void print_dbrec (char *dbname, struct or_dbrec * dbrec) { int i; char *cptr; int blobs_are_possible = FALSE; printf (catgets (dtsearch_catd, MS_dbrec, 1, "---------- System Values for Database '%s' ----------\n"), dbname); printf (catgets (dtsearch_catd, MS_dbrec, 2, "Schema version number (version) is '%s'.\n"), dbrec->or_version); printf (catgets (dtsearch_catd, MS_dbrec, 3, "Maximum object key size (sizeof(objkey)) is %ld bytes.\n"), DtSrMAX_DB_KEYSIZE); if (ORD_USEHUGEKEYS & dbrec->or_dbflags) printf (catgets (dtsearch_catd, MS_dbrec, 4, "Optional 'Huge' keys enabled.\n")); printf (catgets (dtsearch_catd, MS_dbrec, 12, "Maximum length of an abstract string (abstrsz) is %d.\n"), dbrec->or_abstrsz); if (dbrec->or_abstrsz == 0) puts (catgets (dtsearch_catd, MS_dbrec, 14, " (Abstracts are not used in this database).")); else { /* * if they CAN be compressed, say whether or not they * actually are */ if (dbrec->or_hufid != 0L) printf (catgets (dtsearch_catd, MS_dbrec, 20, "Abstracts are %scompressed.\n"), (ORC_COMPABSTR & dbrec->or_compflags) ? "" : "not "); } printf (catgets (dtsearch_catd, MS_dbrec, 22, "Parsing language is number %d, %s.\n"), dbrec->or_language, language_name(dbrec->or_language)); printf (catgets (dtsearch_catd, MS_dbrec, 24, "Minimum word length (minwordsz) is %d.\n"), dbrec->or_minwordsz); printf (catgets (dtsearch_catd, MS_dbrec, 26, "Maximum word length (maxwordsz) is %d.\n"), dbrec->or_maxwordsz); printf (catgets (dtsearch_catd, MS_dbrec, 30, "Number of .d00 slots per object (recslots) is %d.\n"), dbrec->or_recslots); printf (catgets (dtsearch_catd, MS_dbrec, 36, " (Maximum number of database objects is %ld).\n"), 0xffffffL / (long) dbrec->or_recslots); printf (catgets (dtsearch_catd, MS_dbrec, 40, "Huffman compression table id (hufid) is %ld.\n"), dbrec->or_hufid); if (dbrec->or_hufid == 0L) puts (catgets (dtsearch_catd, MS_dbrec, 42, " (Compression is disabled in this database).")); if (dbrec->or_hufid == -1L) puts (catgets (dtsearch_catd, MS_dbrec, 44, " (Specific compression table is not yet determined).")); blobs_are_possible = FALSE; switch (dbrec->or_dbaccess) { case ORA_VARIES: puts (catgets (dtsearch_catd, MS_dbrec, 50, "Engine accessibility to data may vary from object to object.")); blobs_are_possible = TRUE; break; case ORA_NOTAVAIL: puts (catgets (dtsearch_catd, MS_dbrec, 54, "Data objects are not directly accessible from the engine.")); break; case ORA_BLOB: puts (catgets (dtsearch_catd, MS_dbrec, 56, "Data objects are stored internally as blobs.")); blobs_are_possible = TRUE; break; case ORA_REFBLOB: puts (catgets (dtsearch_catd, MS_dbrec, 60, "Only server file references to objects are stored in the blobs.")); break; case ORA_CREFBLOB: puts (catgets (dtsearch_catd, MS_dbrec, 64, "Only client file references to objects are stored in the blobs.")); break; case ORA_REFKEY: puts (catgets (dtsearch_catd, MS_dbrec, 68, "Object keys are server file references to the objects.")); break; case ORA_CREFKEY: puts (catgets (dtsearch_catd, MS_dbrec, 72, "Object keys are client file references to the objects.")); break; case ORA_REFHUGEKEY: puts (catgets (dtsearch_catd, MS_dbrec, 74, "Server file references to objects are " "stored in the 'huge' keys.")); break; case ORA_REFABSTR: puts (catgets (dtsearch_catd, MS_dbrec, 80, "Server file references to objects are stored in the abstracts.")); break; case ORA_CREFABSTR: puts (catgets (dtsearch_catd, MS_dbrec, 86, "Client file references to objects are stored in the abstracts.")); break; default: printf (catgets (dtsearch_catd, MS_dbrec, 90, "Error: meaning of or_dbaccess value (%hd) is unknown.\n"), dbrec->or_dbaccess); blobs_are_possible = TRUE; break; } /* end or_dbaccess switch */ if (blobs_are_possible) { /* * if they CAN be compressed, say whether or not they * actually are */ if (dbrec->or_hufid != 0L) printf (catgets (dtsearch_catd, MS_dbrec, 100, "Repository blobs are %scompressed.\n"), (ORC_COMPBLOB & dbrec->or_compflags) ? "" : "not "); } else puts (catgets (dtsearch_catd, MS_dbrec, 110, "Repository blobs are not used in this database.")); printf (catgets (dtsearch_catd, MS_dbrec, 120, "Database switches (dbflags) are 0x%lx:\n"), dbrec->or_dbflags); printf (catgets (dtsearch_catd, MS_dbrec, 130, " Inverted index %s words exactly as parsed.\n"), (ORD_XWORDS & dbrec->or_dbflags) ? catgets (dtsearch_catd, MS_dbrec, 124, "INCLUDES") : catgets (dtsearch_catd, MS_dbrec, 125, "EXCLUDES")); printf (catgets (dtsearch_catd, MS_dbrec, 140, " Inverted index %s word stems.\n"), (ORD_XSTEMS & dbrec->or_dbflags) ? catgets (dtsearch_catd, MS_dbrec, 124, "INCLUDES") : catgets (dtsearch_catd, MS_dbrec, 125, "EXCLUDES")); printf (catgets (dtsearch_catd, MS_dbrec, 160, " Use of optional 'huge' keys is %s.\n"), (ORD_USEHUGEKEYS & dbrec->or_dbflags) ? catgets (dtsearch_catd, MS_dbrec, 126, "ENABLED") : catgets (dtsearch_catd, MS_dbrec, 127, "DISABLED")); printf (catgets (dtsearch_catd, MS_dbrec, 162, " Mark-for-deletion is %s.\n"), (ORD_NOMARKDEL & dbrec->or_dbflags) ? catgets (dtsearch_catd, MS_dbrec, 127, "DISABLED") : catgets (dtsearch_catd, MS_dbrec, 126, "ENABLED")); printf (catgets (dtsearch_catd, MS_dbrec, 164, " Appendable user notes are %s.\n"), (ORD_NONOTES & dbrec->or_dbflags) ? catgets (dtsearch_catd, MS_dbrec, 127, "DISABLED") : catgets (dtsearch_catd, MS_dbrec, 126, "ENABLED")); printf (catgets (dtsearch_catd, MS_dbrec, 170, " Text characters are %s wide.\n"), (ORD_WIDECHAR & dbrec->or_dbflags) ? catgets (dtsearch_catd, MS_dbrec, 172, "MULTIPLE bytes") : catgets (dtsearch_catd, MS_dbrec, 174, "a SINGLE byte")); printf (catgets (dtsearch_catd, MS_dbrec, 200, "Current number of database objects (reccount) is %ld.\n"), dbrec->or_reccount); printf (catgets (dtsearch_catd, MS_dbrec, 210, "Last currently used slot number (maxdba) is %ld.\n"), dbrec->or_maxdba); for (i = 58; i > 0; i--) putchar ('-'); putchar ('\n'); return; } /* print_dbrec() */
int main (int argc, char **argv) { char *s, *needle; int c, i, done, ret; unsigned drive /* , thisdrive */ ; /* used to store, change drive */ char cwd[MAXPATH], thiscwd[MAXPATH95]; /* used to store, change cwd */ char cwd2[MAXPATH]; /* store cwd of other drive */ /* char drv[MAXDRIVE]; */ /* temporary buffer */ unsigned drv; /* drive found in argument */ /* unsigned maxdrives; */ /* not used */ int invert_search = 0; /* flag to invert the search */ int count_lines = 0; /* flag to whether/not count lines */ int number_output = 0; /* flag to print line numbers */ int ignore_case = 0; /* flag to be case insensitive */ /* FILE *pfile; */ /* file pointer */ int thefile; /* file handler */ nl_catd cat; /* message catalog */ /* struct ffblk ffblk; */ /* findfirst, findnext block */ char file[MAXPATH], longfile[MAXPATH95]; /* Message catalog */ cat = catopen ("find", 0); /* Scan the command line */ c = 1; /* argv[0] is the path of the exectutable! */ /* first, expect all slashed arguments */ while ((c < argc) && (argv[c][0] == '/') ) { /* printf("arg: %s\n",argv[c]); */ switch (argv[c][1]) { case 'c': case 'C': /* Count */ count_lines = 1; break; case 'i': case 'I': /* Ignore */ ignore_case = 1; break; case 'n': case 'N': /* Number */ number_output = 1; break; case 'v': case 'V': /* Not with */ invert_search = 1; break; default: usage (cat); catclose (cat); exit (2); /* syntax error .. return errorlevel 2 */ break; } /* end case */ c++; /* next argument */ } /* end while */ /* Get the string */ if (c >= argc) { /* No string? */ /* printf("no string"); */ usage (cat); catclose (cat); exit (1); } else { /* Assign the string to find */ needle = argv[c]; c++; /* next argument(s), if any: file name(s) */ /* printf("needle: %s\n",needle); */ } /* Store the drive and cwd */ /* findfirst/findnext do not return drive and cwd information, so we have to store the drive & cwd at the beginning, then chdir for each file we scan using findfirst, then chdir back to the initial drive & cwd at the end. This is probably not the most efficient way of doing it, but it works. -jh */ /* _dos_getdrive (&drive); */ /* 1 for A, 2 for B, ... */ drive = getdisk() + 1; /* uses dir.h */ getcwd (cwd, MAXDIR); /* also stores drive letter */ #if 0 /* debugging */ /* printf ("drive=%c\n", (drive+'A'-1)); */ /* printf ("cwd=%s\n", cwd); */ #endif /* debugging */ /* Scan the files for the string */ if ((argc - c) <= 0) { /* No files on command line - scan stdin */ ret = find_str (needle, 0 /* stdin */, invert_search, count_lines, number_output, ignore_case); } else { for (i = c; i < argc; i++) { /* find drive and wd for each file when using findfirst */ /* fnsplit (argv[i], drv, thiscwd, NULL, NULL); */ /* fnsplit is "expensive", so replace it... */ if (argv[i][1] == ':') { drv = toupper(argv[i][0]) - 'A'; strcpy(thiscwd,argv[i]+2); } else { drv = drive - 1; /* default drive */ strcpy(thiscwd,argv[i]); } if (strrchr(thiscwd,'\\') == NULL) { strcpy(thiscwd,"."); /* no dir given */ } else { if (strrchr(thiscwd,'\\') != thiscwd) { strrchr(thiscwd,'\\')[0] = '\0'; /* end string at last \\ */ } else { strcpy(thiscwd,"\\"); /* dir is root dir */ } } if (!LFNConvertToSFN(thiscwd)) { s = catgets (cat, 2, 2, "Cannot change to directory"); /* printf ("FIND: %s: %s\n", argv[i], s); */ write(1,"FIND: ",6); write(1,argv[i],strlen(argv[i])); write(1,": ",2); write(1,s,strlen(s)); write(1,"\r\n",2); } /* printf("drive (0=A:)=%d dir=%s\n", drv, thiscwd); */ /* use findfirst/findnext to expand the filemask */ /* done = findfirst (argv[i], &ffblk, 0); */ done = LFNFirstFile(argv[i], file, longfile); if (done) { /* We were not able to find a file. Display a message and set the exit status. */ s = catgets (cat, 2, 1, "No such file"); /* printf ("FIND: %s: %s\n", argv[i], s); */ write(1,"FIND: ",6); write(1,argv[i],strlen(argv[i])); write(1,": ",2); write(1,s,strlen(s)); write(1,"\r\n",2); } while (!done) { /* We have found a file, so try to open it */ /* set cwd to the filemask */ /* _dos_setdrive (('A' - drv[0] + 1), &maxdrives); */ /* this was the wrong way round! */ (void) setdisk (drv /* drv[0] - 'A' */); /* dir.h */ getcwd(cwd2,MAXDIR); /* remember cwd here, too */ if (chdir (thiscwd) < 0) { s = catgets (cat, 2, 2, "Cannot change to directory"); /* printf ("FIND: %s: %s\n", argv[i], s); */ write(1,"FIND: ",6); write(1,argv[i],strlen(argv[i])); write(1,": ",2); write(1,s,strlen(s)); write(1,"\r\n",2); }; /* open the file, or not */ if ((thefile = open (file, O_RDONLY)) != -1) { /* printf ("---------------- %s\n", ffblk.ff_name); */ write(1,"---------------- ",17); write(1,longfile, strlen(longfile)); write(1,"\r\n",2); ret = find_str (needle, thefile, invert_search, count_lines, number_output, ignore_case); close (thefile); } else { s = catgets (cat, 2, 0, "Cannot open file"); /* printf ("FIND: %s: %s\n", argv[i], s); */ write(1,"FIND: ",6); write(1,argv[i],strlen(argv[i])); write(1,": ",2); write(1,s,strlen(s)); write(1,"\r\n",2); } /* return the cwd */ chdir (cwd2); /* restore cwd on THAT drive */ /* _dos_setdrive (drive, &maxdrives); */ (void) setdisk (drive - 1); /* dir.h */ chdir (cwd); /* find next file to match the filemask */ /* done = findnext (&ffblk); */ done = LFNNextFile(file, longfile); } /* while !done */ LFNFindStop(); } /* for each argv */ } /* else */ /* Done */ catclose (cat); /* RETURN: If the string was found at least once, returns 0. * If the string was not found at all, returns 1. * (Note that find_str.c returns the exact opposite values.) */ exit ( (ret ? 0 : 1) ); return (ret ? 0 : 1); }
void __kmp_i18n_do_catopen( ) { int english = 0; char * lang = __kmp_env_get( "LANG" ); // TODO: What about LC_ALL or LC_MESSAGES? KMP_DEBUG_ASSERT( status == KMP_I18N_CLOSED ); KMP_DEBUG_ASSERT( cat == KMP_I18N_NULLCAT ); english = lang == NULL || // In all these cases English language is used. strcmp( lang, "" ) == 0 || strcmp( lang, " " ) == 0 || // Workaround for Fortran RTL bug DPD200137873 "Fortran runtime resets LANG env var // to space if it is not set". strcmp( lang, "C" ) == 0 || strcmp( lang, "POSIX" ) == 0; if ( ! english ) { // English language is not yet detected, let us continue. // Format of LANG is: [language[_territory][.codeset][@modifier]] // Strip all parts except language. char * tail = NULL; __kmp_str_split( lang, '@', & lang, & tail ); __kmp_str_split( lang, '.', & lang, & tail ); __kmp_str_split( lang, '_', & lang, & tail ); english = ( strcmp( lang, "en" ) == 0 ); }; // if KMP_INTERNAL_FREE( lang ); // Do not try to open English catalog because internal messages are // exact copy of messages in English catalog. if ( english ) { status = KMP_I18N_ABSENT; // mark catalog as absent so it will not be re-opened. return; } cat = catopen( name, 0 ); // TODO: Why do we pass 0 in flags? status = ( cat == KMP_I18N_NULLCAT ? KMP_I18N_ABSENT : KMP_I18N_OPENED ); if ( status == KMP_I18N_ABSENT ) { if (__kmp_generate_warnings > kmp_warnings_low) { // AC: only issue warning in case explicitly asked to int error = errno; // Save errno immediately. char * nlspath = __kmp_env_get( "NLSPATH" ); char * lang = __kmp_env_get( "LANG" ); // Infinite recursion will not occur -- status is KMP_I18N_ABSENT now, so // __kmp_i18n_catgets() will not try to open catalog, but will return default message. __kmp_msg( kmp_ms_warning, KMP_MSG( CantOpenMessageCatalog, name ), KMP_ERR( error ), KMP_HNT( CheckEnvVar, "NLSPATH", nlspath ), KMP_HNT( CheckEnvVar, "LANG", lang ), __kmp_msg_null ); KMP_INFORM( WillUseDefaultMessages ); KMP_INTERNAL_FREE( nlspath ); KMP_INTERNAL_FREE( lang ); } } else { // status == KMP_I18N_OPENED int section = get_section( kmp_i18n_prp_Version ); int number = get_number( kmp_i18n_prp_Version ); char const * expected = __kmp_i18n_default_table.sect[ section ].str[ number ]; // Expected version of the catalog. kmp_str_buf_t version; // Actual version of the catalog. __kmp_str_buf_init( & version ); __kmp_str_buf_print( & version, "%s", catgets( cat, section, number, NULL ) ); // String returned by catgets is invalid after closing the catalog, so copy it. if ( strcmp( version.str, expected ) != 0 ) { __kmp_i18n_catclose(); // Close bad catalog. status = KMP_I18N_ABSENT; // And mark it as absent. if (__kmp_generate_warnings > kmp_warnings_low) { // AC: only issue warning in case explicitly asked to // And now print a warning using default messages. char const * name = "NLSPATH"; char const * nlspath = __kmp_env_get( name ); __kmp_msg( kmp_ms_warning, KMP_MSG( WrongMessageCatalog, name, version.str, expected ), KMP_HNT( CheckEnvVar, name, nlspath ), __kmp_msg_null ); KMP_INFORM( WillUseDefaultMessages ); KMP_INTERNAL_FREE( (void *) nlspath ); } // __kmp_generate_warnings }; // if __kmp_str_buf_free( & version ); }; // if } // func __kmp_i18n_do_catopen
void show_main_help(Widget w, XtPointer clientData, XtPointer cbs) { int ac; Arg al[10]; Calendar *c = calendar; Props_pu *p = (Props_pu *) c->properties_pu; Widget selWidget = NULL; int status = DtHELP_SELECT_ERROR; ac = 0; XtSetArg(al[ac], DtNhelpType, DtHELP_TYPE_TOPIC); ac++; switch ((int)clientData) { case HELP_OVERVIEW: XtSetArg(al[ac], DtNhelpVolume, "Calendar"); ac++; XtSetArg(al[ac], DtNlocationId, "_HOMETOPIC"); ac++; break; case HELP_USINGHELP: XtSetArg(al[ac], DtNhelpVolume, "Help4Help"); ac++; XtSetArg(al[ac], DtNlocationId, "_HOMETOPIC"); ac++; break; case HELP_TASKS: XtSetArg(al[ac], DtNhelpVolume, "Calendar"); ac++; XtSetArg(al[ac], DtNlocationId, "TASKS"); ac++; break; case HELP_REFERENCE: XtSetArg(al[ac], DtNhelpVolume, "Calendar"); ac++; XtSetArg(al[ac], DtNlocationId, "REFERENCE"); ac++; break; case HELP_ABOUTCALENDAR: XtSetArg(al[ac], DtNhelpVolume, "Help4Help"); ac++; XtSetArg(al[ac], DtNlocationId, "_COPYRIGHT"); ac++; break; case HELP_TOC: XtSetArg(al[ac], DtNhelpVolume, "Calendar"); ac++; XtSetArg(al[ac], DtNlocationId, "TOC"); ac++; break; case HELP_ONITEM: while (!XtIsSubclass(w, applicationShellWidgetClass)) w = XtParent(w); status = DtHelpReturnSelectedWidgetId(w, NULL, &selWidget); switch ((int)status) { case DtHELP_SELECT_ERROR: printf(catgets(c->DT_catd, 1, 350, "Selection Error, cannot continue\n")); break; case DtHELP_SELECT_VALID: while (selWidget != NULL) { if ((XtHasCallbacks(selWidget, XmNhelpCallback) == XtCallbackHasSome)) { XtCallCallbacks((Widget)selWidget, XmNhelpCallback,NULL); break; } else selWidget = XtParent(selWidget); } break; case DtHELP_SELECT_ABORT: return; case DtHELP_SELECT_INVALID: { char *title = XtNewString(catgets(c->DT_catd, 1, 110, "Calendar : Error - Help")); char *text = XtNewString(catgets(c->DT_catd, 1, 352, "You must select a component within your application.")); char *ident1 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue")); dialog_popup(c->frame, DIALOG_TITLE, title, DIALOG_TEXT, text, BUTTON_IDENT, 1, ident1, DIALOG_IMAGE, p->xm_error_pixmap, NULL); XtFree(ident1); XtFree(text); XtFree(title); return; } } break; default: XtSetArg(al[ac], DtNhelpVolume, "Calendar"); ac++; XtSetArg(al[ac], DtNlocationId, "_HOMETOPIC"); ac++; break; } display_help(c, al, ac); }
/* XXX: negative 'num' ? (REGR) */ char * strsignal(int num) { static char ebuf[NL_TEXTMAX]; char tmp[20]; size_t n; int signum; char *t, *p; #if defined(NLS) int saved_errno = errno; nl_catd catd; catd = catopen("libc", NL_CAT_LOCALE); #endif if (num > 0 && num < sys_nsig) { n = strlcpy(ebuf, #if defined(NLS) catgets(catd, 2, num, sys_siglist[num]), #else sys_siglist[num], #endif sizeof(ebuf)); } else { n = strlcpy(ebuf, #if defined(NLS) catgets(catd, 2, 0xffff, UPREFIX), #else UPREFIX, #endif sizeof(ebuf)); } signum = num; if (num < 0) signum = -signum; t = tmp; do { *t++ = "0123456789"[signum % 10]; } while (signum /= 10); if (num < 0) *t++ = '-'; p = (ebuf + n); *p++ = ':'; *p++ = ' '; for (;;) { *p++ = *--t; if (t <= tmp) break; } *p = '\0'; #if defined(NLS) catclose(catd); errno = saved_errno; #endif return (ebuf); }
int main(int argc, char *argv[]) { char *load_file = (char *)NULL; /* DB load path/file name */ char *optstring; /* Command option string */ char *logfile = NULL; /* Log file name for samfsrestore -g option */ struct sam_stat sb; int option; /* Current getopt option being processed */ int io_sz, read_size; int len; operator_t operator; /* Operator data */ shm_alloc_t master_shm; /* Master shared memory structure */ program_name = basename(argv[0]); operation = NONE; replace_newer = false; replace = false; swapped = false; verbose = false; quiet = false; noheaders = false; strip_slashes = false; list_by_inode = false; online_data = false; partial_data = false; scan_only = false; unarchived_data = false; use_file_list = false; read_buffer_size = write_buffer_size = CSD_DEFAULT_BUFSZ; block_size = 0; memset(&csd_header, '\0', sizeof (csd_header)); CustmsgInit(0, NULL); if ((Initial_path = getcwd(NULL, (MAXPATHLEN + 1))) == NULL) { error(1, errno, catgets(catfd, SET, 590, "cannot getcwd()")); } /* * If basename is samfsrestore, fake out "r" option; if * samfsdump, fake out "c" option. Allow redundant specification * specifications like "samfsrestore r", "samfsdump c". Allow * "samfsrestore t" to override "r" option so that we look * like "ufsrestore t". If basename is none of the above, then * user must specify one of c,r,t,O. */ if (strcmp(program_name, "samfsrestore") == 0) { operation = RESTORE; optstring = RESTORE_OPT; qfs = false; } else if (strcmp(program_name, "samfsdump") == 0) { operation = DUMP; optstring = DUMP_OPT; qfs = false; } else if (strcmp(program_name, "qfsdump") == 0) { operation = DUMP; optstring = QFSDUMP_OPT; qfs = true; } else if (strcmp(program_name, "qfsrestore") == 0) { operation = RESTORE; optstring = RESTORE_OPT; qfs = true; } if (operation == NONE) { error(1, 0, catgets(catfd, SET, 13508, "Improper invocation of SAM-FS csd " "utility %s"), program_name); } for (nexcluded = CSD_MAX_EXCLUDED - 1; nexcluded >= 0; nexcluded--) { excluded[nexcluded] = NULL; } nexcluded = 0; for (nincluded = CSD_MAX_INCLUDED - 1; nincluded >= 0; nincluded--) { included[nincluded] = NULL; } nincluded = 0; while ((option = getopt(argc, argv, optstring)) != EOF) { switch (option) { case 'B': /* select buffer size */ io_sz = atoi(optarg) * 512; if (io_sz < CSD_MIN_BUFSZ || io_sz > CSD_MAX_BUFSZ) { error(1, 0, catgets(catfd, SET, 13509, "Invalid buffer size, must " "be >= %d and <= %d, " "specified in 512b units"), CSD_MIN_BUFSZ/512, CSD_MAX_BUFSZ/512); } read_buffer_size = write_buffer_size = io_sz; break; case 'b': /* select blocking factor */ io_sz = atoi(optarg) * 512; if (io_sz < 0 || io_sz > CSD_MAX_BUFSZ) { error(1, 0, catgets(catfd, SET, 13510, "Invalid blocking factor, " "must be >= 0 and <= %d, " "specified in 512b units"), CSD_MAX_BUFSZ/512); } block_size = io_sz; break; case 'd': /* enable debug messages */ debugging = 1; break; case 'D': /* enable directio */ Directio++; break; case 'I': /* file of paths to process */ if (nincluded > CSD_MAX_INCLUDED) { error(1, 0, catgets(catfd, SET, 13537, "Maximum -I (include file) entries exceeded, max. is %d."), CSD_MAX_INCLUDED); } included[nincluded] = optarg; len = strlen(optarg); if (len > 0) { *(included[nincluded] + len) = '\0'; nincluded++; } else { error(1, 0, catgets(catfd, SET, 13538, "-I (include file) entry " "<%s> invalid"), optarg); } break; case 'X': /* excluded directory list */ if (nexcluded > CSD_MAX_EXCLUDED) { error(1, 0, catgets(catfd, SET, 13520, "Maximum -X (excluded " "directory) entries " "exceeded, max. is %d."), CSD_MAX_EXCLUDED); } excluded[nexcluded] = optarg; len = strlen(optarg); if (len > 0) { *(excluded[nexcluded] + len) = '\0'; nexcluded++; } else { error(1, 0, catgets(catfd, SET, 13521, "-X (excluded directory) entry <%s> " "invalid"), optarg); } break; case 'f': /* specify dump file */ dump_file = optarg; break; case 'g': /* specify log file */ logfile = optarg; break; case 'H': /* no headers */ noheaders = true; break; case 'i': /* print inode numbers */ ls_options |= LS_INODES; break; case 'l': /* print 1 line ls */ verbose = true; ls_options |= LS_LINE1; break; case 'n': /* Deprecated. Do not break script. */ break; case 'P': /* dump partial online data */ partial_data = true; break; case 'q': /* Do not report damage warnings */ quiet = true; break; case 'r': /* replace file if dump is newer */ replace_newer = true; break; case 'R': /* replace file */ replace = true; break; case 's': /* strip leading /'s */ strip_slashes = true; break; case 'S': /* scan only */ scan_only = true; break; case 't': /* list dump file */ if (operation & DUMP) { error(1, 0, catgets(catfd, SET, 941, "Do not specify 't' option.")); } /* samfsrestore t is LIST, not RESTORE */ operation = LIST; break; case 'T': /* statistics mode */ statistics = true; break; case 'u': /* dump unarchived data */ unarchived_data = true; break; case 'U': /* dump online data */ online_data = true; break; case 'v': /* verbose mode */ verbose = true; break; case 'W': /* warning mode, allowed for historical reasons */ break; case '2': /* print 2 line ls */ verbose = true; ls_options |= LS_LINE2; break; case 'Y': /* file list for dump */ use_file_list = true; break; case 'Z': /* generate database load file */ load_file = optarg; break; case '?': usage(); /* doesn't return */ break; } } if (scan_only) { /* clear dump related flags */ online_data = partial_data = unarchived_data = false; } if (block_size && (block_size > read_buffer_size)) { block_size = read_buffer_size; } if (operation == DUMP && use_file_list) { operation = LISTDUMP; } if (debugging) { int i; fprintf(stderr, "\nCOMMAND ARGUMENT VALUES\n"); fprintf(stderr, "operation = 0x%x\n", operation); fprintf(stderr, "debugging = %d\n", debugging); fprintf(stderr, "dump_file = %s\n", ((dump_file != (char *)NULL) ? dump_file : "UNDEFINED")); fprintf(stderr, "logfile = %s\n", ((logfile != (char *)NULL) ? logfile : "UNDEFINED")); fprintf(stderr, "noheaders = %d\n", noheaders); fprintf(stderr, "verbose = %d\n", verbose); fprintf(stderr, "quiet = %d\n", quiet); fprintf(stderr, "qfs = %d\n", qfs); fprintf(stderr, "replace = %d\n", replace); fprintf(stderr, "replace_newer = %d\n", replace_newer); fprintf(stderr, "strip_slashes = %d\n", strip_slashes); fprintf(stderr, "ls_options = 0x%x\n", ls_options); fprintf(stderr, "load_file = %s\n", ((load_file != (char *)NULL) ? load_file : "UNDEFINED")); fprintf(stderr, "online_data = %d\n", online_data); fprintf(stderr, "partial_data = %d\n", partial_data); fprintf(stderr, "scan_only = %d\n", scan_only); fprintf(stderr, "unarchived_data = %d\n", unarchived_data); fprintf(stderr, "use_file_list = %d\n", use_file_list); fprintf(stderr, "read buffer size = %ld\n", read_buffer_size); fprintf(stderr, "write buffer size = %ld\n", write_buffer_size); fprintf(stderr, "blocking factor = %ld\n", block_size); for (i = optind; i < argc; i++) { fprintf(stderr, "File argument %d = %s\n", (i - optind + 1), argv[i]); } fprintf(stderr, "END COMMAND ARGUMENT VALUES\n\n"); } /* * If dump file has not been specified, exit with error and usage */ if ((!scan_only) && dump_file == (char *)NULL) { error(0, 0, catgets(catfd, SET, 5019, "%s: Dump file name not specified (-f)"), program_name); usage(); } /* * Access master shared memory segment */ if ((master_shm.shared_memory = (shm_ptr_tbl_t *) sam_mastershm_attach(0, SHM_RDONLY)) == (void *)-1) { /* * If shared memory not available, effective ID must be * super-user. */ if (geteuid() != 0) { error(1, 0, catgets(catfd, SET, 100, "%s may be run only by super-user.\n"), program_name); } } else { /* * If operator is not super-user, issue error message and exit */ SET_SAM_OPER_LEVEL(operator); shmdt((char *)master_shm.shared_memory); if (!SAM_ROOT_LEVEL(operator)) { error(1, 0, catgets(catfd, SET, 100, "%s may be run only by super-user.\n"), program_name); } } /* * Open dump file and process header */ switch (operation) { case NONE: error(1, 0, catgets(catfd, SET, 1845, "One of c, r, O or t options must be specified.")); usage(); /* doesn't return */ break; case DUMP: case LISTDUMP: if (!scan_only) { if (strcmp(dump_file, "-") == 0) { CSD_fd = dup(STDOUT); } else { CSD_fd = open(dump_file, O_WRONLY|O_TRUNC|O_CREAT|SAM_O_LARGEFILE, 0666 & ~umask(0)); } close(STDOUT); if (CSD_fd < 0) { error(1, errno, catgets(catfd, SET, 216, "%s: Cannot create dump file"), dump_file); } } break; case RESTORE: case LIST: if (0 == strcmp(dump_file, "-")) { CSD_fd = dup(STDIN); } else { CSD_fd = open(dump_file, O_RDONLY | SAM_O_LARGEFILE); } close(STDIN); if (CSD_fd < 0) { error(1, errno, catgets(catfd, SET, 225, "%s: Cannot open dump file"), dump_file); } if (noheaders) { break; } if (buffered_read(CSD_fd, &csd_header, sizeof (csd_hdr_t)) != sizeof (csd_hdr_t)) { error(1, errno, catgets(catfd, SET, 244, "%s: Header record read error"), dump_file); } if (csd_header.csd_header.magic != CSD_MAGIC) { if (csd_header.csd_header.magic != CSD_MAGIC_RE) { error(1, 0, catgets(catfd, SET, 13529, "%s: Volume is not in dump format."), dump_file); } else { error(0, 0, "Dump file was generated on an " "opposite endian machine"); swapped = true; sam_byte_swap(csd_header_swap_descriptor, &csd_header, sizeof (csd_hdr_t)); } } csd_version = csd_header.csd_header.version; switch (csd_version) { case CSD_VERS_6: case CSD_VERS_5: /* read remainder of extended header */ io_sz = sizeof (csd_hdrx_t) - sizeof (csd_hdr_t); read_size = buffered_read(CSD_fd, (char *)((char *)(&csd_header) + sizeof (csd_hdr_t)), io_sz); if (swapped) { sam_bswap4(&csd_header.csd_header_flags, 1); sam_bswap4(&csd_header.csd_header_magic, 1); sam_bswap8(&csd_header.csd_fs_magic, 1); } if ((read_size != io_sz) || csd_header.csd_header_magic != CSD_MAGIC) { error(1, errno, catgets(catfd, SET, 244, "%s: Header record read error"), dump_file); } break; case CSD_VERS_4: case CSD_VERS_3: case CSD_VERS_2: break; default: error(1, 0, catgets(catfd, SET, 5013, "%s: Header record error: Bad version number (%d)"), dump_file, csd_version); } if (verbose) { printf(catgets(catfd, SET, 972, "Dump created:%s"), ctime((const time_t *)&csd_header.csd_header.time)); } if (debugging) { fprintf(stderr, "Dump created:%s\n", ctime((const time_t *)&csd_header.csd_header.time)); } } if ((logfile != NULL) && (log_st = fopen(logfile, "w")) == NULL) { error(0, errno, "%s", logfile); error(0, 0, catgets(catfd, SET, 1856, "Open failed on (%s)"), logfile); } if ((load_file != NULL)) { if (0 == strcmp(load_file, "-")) { DB_FILE = fdopen(dup(STDOUT), "w"); close(STDOUT); } else if ((DB_FILE = fopen64(load_file, "w")) == NULL) { error(0, errno, "%s", load_file); error(1, 0, catgets(catfd, SET, 1856, "Open failed on (%s)"), load_file); } } switch (operation) { case NONE: break; case DUMP: { char *filename; if (debugging) { fprintf(stderr, "dumping. argc %d, initial " "path '%s' \n", optind, Initial_path); } while ((filename = get_path(argc, argv)) != NULL) { if (debugging) { fprintf(stderr, "dumping path '%s' \n", filename); } /* * Try to make sure we don't dump from a non-SAM-FS * filesystem by calling sam_stat() and checking the * attributes. */ if (sam_stat(filename, &sb, sizeof (sb)) < 0 || ! SS_ISSAMFS(sb.attr)) { BUMP_STAT(errors); BUMP_STAT(errors_dir); error(1, errno, catgets(catfd, SET, 259, "%s: Not a SAM-FS file."), filename); } else { if (SAM_fd != -1) { close(SAM_fd); } SAM_fd = open_samfs(filename); csd_dump_path("initial", filename, (mode_t)sb.st_mode); if (S_ISDIR(sb.st_mode)) { process_saved_dir_list(filename); } } if (chdir(Initial_path) < 0) { error(1, errno, catgets(catfd, SET, 212, "%s: cannot chdir()"), Initial_path); } } } bflush(CSD_fd); break; case LISTDUMP: { char *filename; if (debugging) { fprintf(stderr, "dumping. argc %d, initial " "path '%s' \n", optind, Initial_path); } while ((filename = get_path(argc, argv)) != NULL) { if (debugging) { fprintf(stderr, "dumping path '%s' \n", filename); } if (strcmp(filename, "-") == 0) { DL_FILE = fdopen(dup(STDIN), "r"); close(STDIN); } else if ((DL_FILE = fopen(filename, "r")) == NULL) { error(0, errno, "%s", load_file); error(1, 0, catgets(catfd, SET, 1856, "Open failed on (%s)"), load_file); } if (SAM_fd != -1) { close(SAM_fd); } csd_dump_files(DL_FILE, filename); fclose(DL_FILE); DL_FILE = NULL; } } bflush(CSD_fd); break; case RESTORE: umask(0); cs_restore(strip_slashes, (argc - optind), &argv[optind]); break; case LIST: cs_list((argc - optind), &argv[optind]); } close(CSD_fd); if (statistics) { print_stats(); } return (exit_status); }
char *MPIR_GetNLSMsg( int errclass, int errkind, char *defmsg ) { char *msg = 0; char *lang; char *path; _CheckForDebug(); if (DebugFlag) { PRINTF( "Looking in message catalog for messages\n" ); } if (!opened_msgcat) { opened_msgcat = 1; /* Initialization */ #if defined(LC_MESSAGES) /* FreeBSD doesn't support LC_MESSAGES locale! */ lang = getenv( "LANG" ); if (!lang) lang = "C"; if (DebugFlag) { PRINTF( "setlocale( LC_MESSAGES, %s )\n", lang ); } setlocale( LC_MESSAGES, lang ); #endif errmsg = catopen("mpich.cat",0); if (errmsg == (nl_catd)-1) { /* Try MPICHNLSPATH */ path = getenv( "MPICHNLSPATH" ); if (path) { /* Only a single directory is allowed for now */ char fullpath[1024]; strncpy( fullpath, path, 1023 ); strcat( fullpath, "/mpich.cat" ); if (DebugFlag) { PRINTF( "catopen( %s, 0 )\n", fullpath ); } errmsg = catopen( fullpath, 0 ); if (errmsg == (nl_catd)-1) { strncpy( fullpath, path, 1023 ); strcat( fullpath, "/mpich.En_US.cat" ); if (DebugFlag) { PRINTF( "catopen( %s, 0 )\n", fullpath ); } errmsg = catopen( fullpath, 0 ); } } else { /* Try absolute location */ if (DebugFlag) { PRINTF( "catopen( %s, 0 )\n", "/home/MPI/mpich/lib/mpich.cat" ); } errmsg = catopen( "/home/MPI/mpich/lib/rs6000/mpich.cat", 0 ); } } catavail = (errmsg != (nl_catd)-1) ; } /* Getting a message */ if (usecat && catavail) { /* Args to catgets are nl_catd, setnum, msgnum, defaultmsg */ msg = catgets( errmsg, errclass, errkind + 1, defmsg ); if (DebugFlag) { PRINTF( "catgets( , %d, %d, ) returned %s\n", errclass, errkind + 1, msg ? msg : "<NULL>" ); } } else { msg = defmsg; if (DebugFlag) { PRINTF( "Returning default message %s\n", msg ); } } return msg; }
/* * ----- get_path(int argc, char *argv[]) * * Get the next file or path to dump. */ static char * get_path( int argc, char *argv[]) { char *path; typedef enum {GPINIT = 0, GPFILE, GPCMD, GPDONE} gpse; static gpse gp_state = GPINIT; static char line[MAXPATHLEN + 1]; static FILE *I_str = NULL; static int ni = 0; path = NULL; switch (gp_state) { case GPINIT: if ((optind >= argc) && nincluded == 0) { /* If no paths or file given, default to "." */ path = "."; gp_state = GPDONE; break; } gp_state = GPFILE; /*FALLTHROUGH*/ case GPFILE: while (nincluded > 0) { if (I_str == NULL) { if ((I_str = fopen(included[ni], "r")) == NULL) { error(1, errno, catgets(catfd, SET, 613, "Cannot open %s"), included[ni]); } } path = fgets(line, sizeof (line), I_str); if (path != NULL) { int trim; path += strspn(path, "\t\n "); trim = strcspn(path, "\t\n"); path[trim--] = '\0'; while (trim > 0 && path[trim] == ' ') { path[trim--] = '\0'; } return (path); } else { fclose(I_str); I_str = NULL; nincluded--; ni++; } } gp_state = GPCMD; /*FALLTHROUGH*/ case GPCMD: if (optind >= argc) { path = NULL; gp_state = GPDONE; } else { path = argv[optind++]; } break; case GPDONE: path = NULL; break; } return (path); }
/* * Check archive status. * Determine data from all archive copies */ static void CheckArchiveStatus(void) { char *mn, *vsn; int copy, mask; boolean_t CopyDamaged; for (copy = 0, mask = 1; copy < MAX_ARCHIVE; copy++, mask += mask) { char sflags[5] = "----"; if (!(mask & CopyMask)) continue; if (!(inode.di.arch_status & mask)) continue; vsn = inode.ar.image[copy].vsn; mn = (char *)sam_mediatoa(inode.di.media[copy]); if (*vsn == '\0') vsn = "Blank"; if (*mn == '\0') mn = "??"; if (inode.di.ar_flags[copy]) { if (inode.di.ar_flags[copy] & CF_STALE) sflags[0] = 'S'; if (inode.di.ar_flags[copy] & CF_REARCH) sflags[1] = 'r'; if (inode.di.ar_flags[copy] & CF_DAMAGED) sflags[3] = 'D'; } if (inode.ar.image[copy].n_vsns > 1) { struct sam_section *vsns; struct sam_section *ivsns; offset_t size; int n; if ((vsns = (struct sam_section *)malloc (SAM_SECTION_SIZE( inode.ar.image[copy].n_vsns))) == NULL) { error(ES_Malloc, errno, catgets(catfd, SET, 1606, "malloc: %s\n"), "sam_vsn_stat"); } if ((fullpath == NULL) || (*fullpath == '\0')) { if (errno == 0) { errno = EINVAL; } error(0, errno, catgets(catfd, SET, 1088, "Cannot sam_vsn_stat; file path is NULL.")); if (exit_status < ES_File) exit_status = ES_File; free(vsns); continue; } else if (S_ISSEGS(&inode.di)) { if (sam_segment_vsn_stat(fullpath, copy, (int)inode.di.rm.info.dk.seg.ord, vsns, (int)SAM_SECTION_SIZE( inode.ar.image[copy].n_vsns)) < 0) { error(0, errno, catgets(catfd, SET, 1089, "Cannot sam_segment_vsn_stat %s " "(copy %d, segment %d"), fullpath, (int)copy + 1, (int) inode.di.rm.info.dk.seg.ord + 1); if (exit_status < ES_SVSN_Stat) exit_status = ES_SVSN_Stat; free(vsns); continue; } } else { if (sam_vsn_stat(fullpath, copy, vsns, (int)SAM_SECTION_SIZE( inode.ar.image[copy].n_vsns)) < 0) { error(0, errno, catgets(catfd, SET, 634, "Cannot sam_vsn_stat %s"), fullpath); if (exit_status < ES_VSN_Stat) exit_status = ES_VSN_Stat; free(vsns); continue; } } ivsns = vsns; for (n = 0; n < inode.ar.image[copy].n_vsns; n++, ivsns++) { vsn = ivsns->vsn; size = ivsns->length; CopyDamaged = inode.di.ar_flags[copy] & AR_damaged; AddFile(inode.di.media[copy], vsn, size, CopyDamaged); if (!Damaged || (Damaged && CopyDamaged)) { fprintf(o_st, "%s %s %s %d %d %llx.%llx %lld %s %d\n", mn, vsn, sflags, copy + 1, n, ivsns->position, ivsns->offset, size, fullpath, seg_num); } } free(vsns); } else { offset_t size; offset_t file_offset = inode.ar.image[copy].file_offset; if ((inode.ar.image[copy].arch_flags & SAR_size_block) == 0) { file_offset /= 512; } CopyDamaged = inode.di.ar_flags[copy] & AR_damaged; if (S_ISSEGI(&inode.di)) { /* Inode is index inode. */ size = (offset_t)inode.di.rm.info.dk.seg.fsize; } else { size = (offset_t)inode.di.rm.size; } AddFile(inode.di.media[copy], vsn, size, CopyDamaged); if (!Damaged || (Damaged && CopyDamaged)) { fprintf(o_st, "%s %s %s %d %d %llx.%llx %lld %s %d\n", mn, vsn, sflags, copy + 1, 0, (offset_t)inode.ar.image[copy].position, file_offset, size, fullpath, seg_num); } } } }
static void scale_and_orient_image ( int *scale, int *density, int width, int height, int left, int top, /* in 300ths of an inch */ const char *header, const char *trailer, enum orientation *orient, int position_on_page, enum device device) { Area usable; /* Determine printable area expressed in centipoints. There are 7200 * centipoints to the inch. The width and height parameters passed in * are expressed in 300ths of an inch, therefore a 24x conversion factor * is used on the parameter values. The default page dimensions STDWIDTH * and STDHEIGHT are expressed in inches so must be multiplied by 7200 * to convert to centipoints. */ page.width = (width >= 0) ? width * 24 : STDWIDTH * 7200; page.height = (height >= 0) ? height * 24 : STDHEIGHT * 7200; /* Paintjet Xl has a mechanical form feed, not a strip feed. It has * a slop of about 1/4 to 1/2 of an inch at the top and bottom. * deduct it from the page height. */ if (device == PJETXL) page.height = page.height - 7200; /* Determine the area usable for the image. This area will be smaller * than the total printable area if margins or header/trailer strings * have been specified. Margins, like width and height discussed above, * are expressed in 300ths of an inch and must be converted to centipoints. * Header and trailer strings each reduce the available image height * by 1/6 inch, or 1200 centipoints (aka CHARHEIGHT). */ usable.width = page.width - ((left > 0) ? (left * 24) : 0); usable.height = page.height - ((top > 0) ? (top * 24) : 0) - ((header) ? CHARHEIGHT : 0) - ((trailer) ? CHARHEIGHT : 0); /* Quit here if there is no usable image space. */ if ((usable.width <= 0) || (usable.height <= 0)) { fatal_err((catgets(nlmsg_fd,NL_SETN,4, "No space available on page for image."))); } /* Determine image orientation. The orientation will only be changed if * it was not specified by a command line option. Portrait mode will be * used if either the usable printing area or the image area are square. * Portrait mode will also be used if the long dimensions of the usable * printing area and the image area match, otherwise landscape mode is * used. Portrait mode really means "don't rotate" and landscape mode * means "rotate". */ if (*orient == UNSPECIFIED) { if ((usable.width == usable.height) || (xwd_header.pixmap_width == xwd_header.pixmap_height)) *orient = PORTRAIT; else *orient = ((usable.width < usable.height) == (xwd_header.pixmap_width < xwd_header.pixmap_height)) ? PORTRAIT : LANDSCAPE; } /* Set the dots-per-inch print density if it was not specified */ if (*density <= 0) { switch(device) { case LJET: *density = 300; break; case PJET: *density = 90; break; case PJETXL: default: *density = 180; break; } } /* Fit image to available area if scale was not specified */ if (*scale <= 0) *scale = scale_raster(*density, *orient, usable); /* Determine image clipping limits */ set_image_limits(*scale, *density, *orient, usable); /* Determine header/trailer string length clipping */ set_header_trailer_limits((char *)header, (char *)trailer, usable.width); /* Calculate locations for page layout */ set_print_locations(*scale, *density, top, left, header, trailer, *orient, position_on_page); }
static void tilde_help(void) { /* a simple routine to print out what is available at this level */ PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgAvailOpts, "\n\r(Available options at this point are:\n\r\n\r")); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgHelpMenu, "\t%c?\tPrint this help menu.\n\r"), escape_char); if (escape_char == '~') /* doesn't make sense otherwise... */ PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgAddLine, "\t~~\tAdd line prefixed by a single '~' character.\n\r")); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgBCC, "\t%cb\tChange the addresses in the Blind-carbon-copy list.\n\r"), escape_char); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgCC, "\t%cc\tChange the addresses in the Carbon-copy list.\n\r"), escape_char); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgEmacs, "\t%ce\tInvoke the Emacs editor on the message, if possible.\n\r"), escape_char); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgAddMessage, "\t%cf\tAdd the specified message or current.\n\r"), escape_char); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgToCCBCC, "\t%ch\tChange all available headers (to, cc, bcc, subject).\n\r"), escape_char); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgSameCurrentPrefix, "\t%cm\tSame as '%cf', but with the current 'prefix'.\n\r"), escape_char, escape_char); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgUserEditor, "\t%co\tInvoke a user specified editor on the message.\n\r"), escape_char); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgPrintMsg, "\t%cp\tPrint out message as typed in so far.\n\r"), escape_char); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgReadFile, "\t%cr\tRead in the specified file.\n\r"), escape_char); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgSubject, "\t%cs\tChange the subject of the message.\n\r"), escape_char); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgTo, "\t%ct\tChange the addresses in the To list.\n\r"), escape_char); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgVi, "\t%cv\tInvoke the Vi visual editor on the message.\n\r"), escape_char); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgUnixCmd, "\t%c!\tExecute a UNIX command (or give a shell if no command).\n\r"), escape_char); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgAddUnixCmd, "\t%c<\tExecute a UNIX command adding the output to the message.\n\r"), escape_char); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgEndMsg, "\t. \tby itself on a line (or a control-D) ends the message.\n\r")); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgContinue, "Continue.)\n\r")); }
int abmfP_write_action_function( GenCodeInfo genCodeInfo, ABObj action ) { int rc = 0; /* return code */ BOOL isTTCB = FALSE; BOOL ss_cb = FALSE; File codeFile = genCodeInfo->code_file; BOOL topUserSegWritten = FALSE; BOOL bottomUserSegWritten = FALSE; BOOL funcBodyWritten = FALSE; BOOL funcEndWritten = FALSE; BOOL actionPrintfWritten = FALSE; int return_value = 0; ABObj fromObj = obj_get_from(action); ABObj actualFromObj = NULL; ABObj toObj = obj_get_to(action); ABObj module = NULL; char actionName[1024]; char actionPrintf[1024]; abmfP_gencode_enter_func(genCodeInfo); abmfP_ip_obj(genCodeInfo) = obj_get_to(action); util_strncpy(actionName, abmfP_get_action_name(action), 1024); sprintf(actionPrintf, "printf(\"action: %s()\\n\");\n", actionName); /*** *** START OF FUNCTION ***/ switch (obj_get_when(action)) { case AB_WHEN_AFTER_CREATED: /* * post-create procs have the signature of an Xt Callback, * although they are called as conventional functions. */ fromObj = obj_get_from(action); actualFromObj = get_actual_from_obj(action); abmfP_write_xm_callback_begin(genCodeInfo, FALSE, actionName); write_instance_ptr_var(genCodeInfo, actualFromObj, get_from_var_name(), "callData", TRUE, NULL); abio_puts(genCodeInfo->code_file, nlstr); break; case AB_WHEN_DRAGGED_FROM: { abio_printf(genCodeInfo->code_file, abmfP_lib_default_dragCB->def, /* this is a format string */ actionName,actionName,actionName, actionName,actionName, actionName); abio_puts(genCodeInfo->code_file, "\n\n"); /* these are all in the "library" definition */ topUserSegWritten = TRUE; bottomUserSegWritten = TRUE; funcBodyWritten = TRUE; funcEndWritten = TRUE; actionPrintfWritten = TRUE; } break; case AB_WHEN_DROPPED_ON: { abio_printf(genCodeInfo->code_file, abmfP_lib_default_dropCB->def, /* this is a format string */ actionName,actionName,actionName,actionName); abio_puts(genCodeInfo->code_file, "\n\n"); /* these are all in the "library" definition */ topUserSegWritten = TRUE; bottomUserSegWritten = TRUE; funcBodyWritten = TRUE; funcEndWritten = TRUE; actionPrintfWritten = TRUE; } break; case AB_WHEN_TOOLTALK_QUIT: case AB_WHEN_TOOLTALK_DO_COMMAND: case AB_WHEN_TOOLTALK_GET_STATUS: case AB_WHEN_TOOLTALK_PAUSE_RESUME: isTTCB = TRUE; abio_printf(codeFile, begin_tt_callback_body, actionName); abmfP_write_c_block_begin(genCodeInfo); write_tooltalk_cb_vars(genCodeInfo, action); break; case AB_WHEN_SESSION_RESTORE: ss_cb = TRUE; abio_printf(codeFile, begin_ss_restore_callback_body, abmfP_get_action_name(action)); abmfP_write_c_block_begin(genCodeInfo); write_ss_cb_vars(genCodeInfo, action); break; case AB_WHEN_SESSION_SAVE: ss_cb = TRUE; abio_printf(codeFile, begin_ss_save_callback_body, abmfP_get_action_name(action)); abmfP_write_c_block_begin(genCodeInfo); write_ss_cb_vars(genCodeInfo, action); break; default: abmfP_write_xm_callback_begin(genCodeInfo, FALSE, actionName); break; } /* switch obj_get_when() */ /***** ***** TOP USER SEGMENT *****/ if (!topUserSegWritten) { STRING contents = (actionPrintfWritten? NULL:(isTTCB? actionPrintf:NULL)); abmfP_write_user_var_and_code_seg(genCodeInfo, contents); abio_puts(codeFile, nlstr); topUserSegWritten = TRUE; if (contents != NULL) { actionPrintfWritten = TRUE; } } /*** *** FUNCTION BODY ***/ if (isTTCB) { write_tooltalk_cb_body1(genCodeInfo, action); abmfP_write_user_code_seg(genCodeInfo, NULL); write_tooltalk_cb_body2(genCodeInfo, action); funcBodyWritten = TRUE; bottomUserSegWritten = TRUE; } else if (ss_cb) { write_ss_cb_body1(genCodeInfo, action); abmfP_write_user_code_seg(genCodeInfo, NULL); write_ss_cb_body2(genCodeInfo, action); funcBodyWritten = TRUE; bottomUserSegWritten = TRUE; } else if (!funcBodyWritten) switch (obj_get_func_type(action)) { case AB_FUNC_BUILTIN: rc = abmfP_write_builtin_action(genCodeInfo, action, TRUE); return_if_err(rc,rc); funcBodyWritten = TRUE; break; case AB_FUNC_USER_DEF: abmfP_write_user_start_comment(genCodeInfo, "vvv Add C code below vvv"); abmfP_write_user_end_comment(genCodeInfo, "^^^ Add C code above ^^^"); bottomUserSegWritten = TRUE; funcBodyWritten = TRUE; break; case AB_FUNC_CODE_FRAG: abio_puts(codeFile, obj_get_func_code(action)); funcBodyWritten = TRUE; break; case AB_FUNC_ON_ITEM_HELP: abio_printf(codeFile, "dtb_do_onitem_help();\n"); funcBodyWritten = TRUE; break; case AB_FUNC_HELP_VOLUME: abio_printf(codeFile, "dtb_show_help_volume_info(\"%s\", \"%s\");\n", istr_string(action->info.action.volume_id), istr_string(action->info.action.location)); funcBodyWritten = TRUE; break; default: { char *obj_name_string = obj_get_name(fromObj); util_printf_err(catgets(Dtb_project_catd, 1, 78, "unknown function type for action from object, %s"), obj_name_string); return_code(ERR); } break; } /***** ***** BOTTOM USER SEGMENT *****/ if (!bottomUserSegWritten) { STRING contents = (actionPrintfWritten? NULL:actionPrintf); abmfP_write_user_code_seg(genCodeInfo, contents); bottomUserSegWritten = TRUE; if (contents != NULL) { actionPrintfWritten = TRUE; } } /***** ***** FUNCTION END *****/ if (!funcEndWritten) { abmfP_write_c_func_end(genCodeInfo, NULL); funcEndWritten = TRUE; } epilogue: abmfP_gencode_exit_func(genCodeInfo); return return_value; }
static void read_in_messages(FILE *fd, char *buffer) { /** Read the specified messages into the open file. If the first character of "buffer" is 'm' then prefix it, other- wise just stream it in straight...Since we're using the pipe to 'readmsg' we can also allow the user to specify patterns and such too... **/ FILE *myfd; char local_buffer[SLEN], *arg; int add_prefix=0, mindex; int n; int lines = 0, nchars = 0; add_prefix = tolower(buffer[0]) == 'm'; /* strip whitespace to get argument */ for(arg = &buffer[1]; whitespace(*arg); arg++) ; /* a couple of quick checks */ if(curr_folder.num_mssgs < 1) { PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmNoMessageReadContinue, "(No messages to read in! Continue.)\n\r")); return; } if (isdigit(*arg)) { if((mindex = atoi(arg)) < 1 || mindex > curr_folder.num_mssgs) { sprintf(local_buffer, catgets(elm_msg_cat, ElmSet, ElmValidNumbersBetween, "(Valid message numbers are between 1 and %d. Continue.)\n\r"), curr_folder.num_mssgs); PutLine(-1, -1, local_buffer); return; } } /* dump state information for "readmsg" to use */ if (create_folder_state_file() != 0) return; /* go run readmsg and get output */ sprintf(local_buffer, "%s -- %s", readmsg, arg); if ((myfd = popen(local_buffer, "r")) == NULL) { PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmCantFindReadmsg, "(Can't find 'readmsg' command! Continue.)\n\r")); (void) remove_folder_state_file(); return; } dprint(5, (debugfile, "** readmsg call: \"%s\" **\n", local_buffer)); while ((n = mail_gets(local_buffer, SLEN, myfd))) { nchars += n; if (local_buffer[n-1] == '\n') lines++; if (add_prefix) fprintf(fd, "%s", prefixchars); fwrite(local_buffer, 1, n, fd); } pclose(myfd); (void) remove_folder_state_file(); if (lines == 0) { PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmEditmsgCouldntAdd, "(Couldn't add the requested message. Continue.)\n\r")); return; } if (lines == 1) PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmAddedLine, "\n\r(Added 1 line [")); else PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmAddedLinePlural, "\n\r(Added %d lines ["), lines); if (nchars == 1) PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmAddedChar, "1 char] ")); else PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmAddedCharPlural, "%d chars] "), nchars); PutLine(-1, -1, catgets(elm_msg_cat, ElmSet, ElmAddedToMessage, "to message. Continue.)\n\r")); return; }
/* ** determine which builtin action and write the appropriate code. */ static int write_builtin_action( GenCodeInfo genCodeInfo, ABObj action, ABObj toObj, AB_BUILTIN_ACTION builtin_action, STRING actionTKResource, /* in toolkit */ STRING actionResource /* in source code */ ) { #define IS(type) (obj_get_func_type(action) ==(type)) #define SVAL(action) ((STRING)obj_get_arg_string(action)) #define IVAL(action) ((int)obj_get_arg_int(action)) File codeFile = genCodeInfo->code_file; int return_value = 0; if (!codeFile || !action || !toObj || !builtin_action) return return_value; switch (builtin_action) { case AB_STDACT_ENABLE: abio_print_line(codeFile, NULL); abio_print_line(codeFile, "XtSetSensitive(%s, True);", abmfP_get_c_name(genCodeInfo, toObj)); break; case AB_STDACT_DISABLE: abio_print_line(codeFile, NULL); abio_print_line(codeFile, "XtSetSensitive(%s, False);", abmfP_get_c_name(genCodeInfo, toObj)); break; case AB_STDACT_SHOW: switch((obj_get_root(toObj))->type) { case AB_TYPE_BASE_WINDOW: abio_print_line(codeFile, "XtPopup(%s, XtGrabNone);", abmfP_get_c_name(genCodeInfo, toObj)); break; case AB_TYPE_DIALOG: case AB_TYPE_FILE_CHOOSER: default: abio_print_line(codeFile, "XtManageChild(%s);", abmfP_get_c_name(genCodeInfo, toObj)); break; } break; case AB_STDACT_HIDE: switch((obj_get_root(toObj))->type) { case AB_TYPE_BASE_WINDOW: abio_print_line(codeFile, "XtPopdown(%s);", abmfP_get_c_name(genCodeInfo, toObj)); break; case AB_TYPE_DIALOG: case AB_TYPE_FILE_CHOOSER: default: abio_print_line(codeFile, "XtUnmanageChild(%s);", abmfP_get_c_name(genCodeInfo, toObj)); break; } break; case AB_STDACT_SET_LABEL: /* check toObj for root */ if ( obj_get_label_type(obj_get_root(toObj)) == AB_LABEL_GLYPH) { abio_printf(codeFile, "%s(%s, ", abmfP_lib_set_label_from_image_file->name, abmfP_get_c_name(genCodeInfo, toObj)); abio_put_string(codeFile, SVAL(action)); abio_puts(codeFile, ");\n"); } else { assert(actionTKResource != NULL); printf_setval(genCodeInfo, toObj, actionTKResource, SVAL(action), NULL); } break; case AB_STDACT_SET_VALUE: printf_setval(genCodeInfo, toObj, actionTKResource, IVAL(action), NULL); break; case AB_STDACT_SET_TEXT: printf_setval(genCodeInfo, toObj, actionTKResource, SVAL(action), NULL); break; /* case AB_STDACT_SHOW_HELP: */ /* abio_print_line(codeFile, NULL); */ /* abio_print_line(codeFile, */ /* "XtCallCallbacks(%s,XmNhelpCallback,(XtPointer)NULL);", */ /* abmfP_get_c_name(genCodeInfo, toObj)); */ /* break; */ default: { static char msg[255]; if (obj_get_name(action) != NULL) { char *action_name = obj_get_name(action); sprintf(msg, catgets(Dtb_project_catd, 1, 76, "Unknown action name, %s"), action_name); } else { int action_type = obj_get_func_builtin(action); sprintf(msg, catgets(Dtb_project_catd, 1, 77, "Unknown action type, %d"), action_type); } util_error(msg); return_value = ERR_INTERNAL; /* * return msg; Just print message and go on - JT */ } break; } /* switch func.value.builtin */ return return_value; #undef IS #undef SVAL #undef IVAL }
/* dblk.path may be NULL */ int open_dblk (DBLK ** dblist, int numpages, int debugging) { DBLK *db, *bad_db, **lastlink; int i; size_t totlen = 0L; char *allnames; int vistano = 0; char *srcptr, *targptr; char temp_file_name[1024]; char sprintbuf[1024]; struct stat statbuf; char open_mode [8]; if (debugging) fprintf (aa_stderr, PROGNAME"76 " "Entering open_dblks(). db_oflag==%d.\n", db_oflag); if (dblist == NULL || numpages < 8) { BAD_INPUT: sprintf (sprintbuf, catgets (dtsearch_catd, MS_oeinit, 99, "%s Programming Error: Invalid input to open_dblk()."), PROGNAME "99"); DtSearchAddMessage (sprintbuf); return FALSE; } if (*dblist == NULL) /* empty list of dblks */ goto BAD_INPUT; if (debugging) { fprintf (aa_stderr, PROGNAME "96 Current list of dblks:\n"); for (db = *dblist; db != NULL; db = db->link) { targptr = sprintbuf; for (i = 0; i < db->ktcount; i++) { *targptr++ = db->keytypes[i].ktchar; } *targptr = 0; fprintf (aa_stderr, "--> DBLK at %p link=%p name='%s' maxhits=%d\n" " keytypes='%s', path='%s'\n", (void *) db, (void *) db->link, db->name, db->maxhits, sprintbuf, NULLORSTR (db->path)); } } /* By doing setpages first, we can trap previously opened databases. * Overflow and transaction locking files are not required. */ d_setpages (numpages, 0); if (db_status != S_OKAY) { DtSearchAddMessage (vista_msg (PROGNAME "389")); return FALSE; } /* ---- PASS #1 ------------------------------------------ * Open nonvista (d99) files. If error, unlink dblk from dblist. * Add up the total string length of surviving paths and database names. * This giant path/file string will be used in the single d_open() * below to find the .dbd files. * While we're at it, set vistano in each dblk. * The open mode depends on the current setting of db_oflag. */ if (db_oflag == O_RDONLY) strcpy (open_mode, "rb"); else strcpy (open_mode, "r+b"); db = *dblist; lastlink = dblist; while (db != NULL) { if (db->path == NULL) db->path = strdup (""); strcpy (temp_file_name, db->path); strcat (temp_file_name, db->name); strcat (temp_file_name, EXT_DTBS); if ((db->iifile = fopen (temp_file_name, open_mode)) == NULL) { if (debugging) fprintf (aa_stderr, PROGNAME "129 UNLINK: cant open '%s'.\n", temp_file_name); sprintf (sprintbuf, catgets (dtsearch_catd, MS_oeinit, 317, "%s Cannot open database file '%s'.\n" " Errno %d = %s\n" " %s is removing '%s' from list of available databases."), PROGNAME "317", temp_file_name, errno, strerror (errno), OE_prodname, db->name); if (errno == ENOENT) strcat (sprintbuf, catgets (dtsearch_catd, MS_oeinit, 318, "\n This can usually be corrected by specifying a valid\n" " database PATH in the site configuration file.")); DtSearchAddMessage (sprintbuf); goto DELETE_DB; } /* * Find and save the timestamp for when the d99 file was * last modified. An engine reinit is forced if it changes * while the engine is running. */ if (fstat (fileno (db->iifile), &statbuf) == -1) { if (debugging) fprintf (aa_stderr, PROGNAME "149 UNLINK: cant get status '%s'.\n", temp_file_name); sprintf (sprintbuf, catgets (dtsearch_catd, MS_oeinit, 1404, "%s Removing database '%s' from list of " "available databases because status is " "unavailable for file %s: %s"), PROGNAME "1404", db->name, temp_file_name, strerror (errno)); DtSearchAddMessage (sprintbuf); goto DELETE_DB; } db->iimtime = statbuf.st_mtime; /* * This dblk is ok so far. Increment pointers and * continue. */ if (debugging) fprintf (aa_stderr, PROGNAME "163 opened '%s'.\n", temp_file_name); db->vistano = vistano++; totlen += strlen (db->path) + strlen (db->name) + 16; lastlink = &db->link; db = db->link; continue; DELETE_DB: /* * This dblk failed in one or more ways. Unlink it and * don't increment pointers. If all dblks unlinked, *dblist * will = NULL. */ bad_db = db; /* temp save */ *lastlink = db->link; db = db->link; free (bad_db); } /* end PASS #1 */ /* quit if no dblks remain */ if (vistano <= 0) { sprintf (sprintbuf, catgets (dtsearch_catd, MS_misc, 8, "%s No valid databases remain."), PROGNAME "265"); DtSearchAddMessage (sprintbuf); return FALSE; } allnames = austext_malloc (totlen + 512, PROGNAME "66", NULL); /* ---- PASS #2 ------------------------------------------ * Build string of accumulated path and database names. */ targptr = allnames; for (db = *dblist; db != NULL; db = db->link) { srcptr = db->path; while (*srcptr != 0) *targptr++ = *srcptr++; srcptr = db->name; while (*srcptr != 0) *targptr++ = *srcptr++; *targptr++ = ';'; } *(--targptr) = 0; /* terminate string */ if (debugging) fprintf (aa_stderr, PROGNAME "150 vista opening databases '%s'\n", allnames); d_open (allnames, "o"); /* replaces OPEN() call from dmacros.h */ if (db_status != S_OKAY) { targptr = austext_malloc (totlen + 128, PROGNAME"239", NULL); sprintf (targptr, catgets (dtsearch_catd, MS_vista, 378, "%s Could not open following database name string:\n '%s'"), PROGNAME"378", allnames); DtSearchAddMessage (targptr); DtSearchAddMessage (vista_msg (PROGNAME"379")); free (allnames); free (targptr); return FALSE; } else if (debugging) fprintf (aa_stderr, " --> vista open successful!\n"); /* From here on, emergency exits MUST close the databases */ austext_exit_dbms = (void (*) (int)) d_close; free (allnames); return TRUE; } /* open_dblk() */
/* Each call joins the two nodes with smallest count * into a single higher level node. If there are more than 2 nodes with * similar 'smallest' counts, then within that group the 2 nodes with the * shortest current bitstring length are joined. * Returns TRUE for each successful lower level join. * Returns FALSE when final join is made at highest level (root). */ static int build_tree (void) { int i, j; int low0 = -1; int low1 = -1; int len0 = 0; int len1 = 0; int curr; /* find 2 lowest counts */ for (i = 0; i < 257; i++) { /* skip over real chars with counts <= 'literal' threshold */ if (literal_coding_on && i != 256 && hctree1[i].count <= literal_threshold) { hctree1[i].sort = MAX_BITLEN + 1; continue; } /* skip over literal if literal coding turned off */ if (i == 256 && !literal_coding_on) { hctree1[256].sort = MAX_BITLEN + 1; continue; } /* * Ascend to highest tree level for current table entry, * putting length of bitstring into sort field. Save * highest tree level in curr. */ hctree1[i].sort = 0; for (j = i; j != -1; j = hctree1[j].father) { hctree1[i].sort++; curr = j; } /* * sanity checks after ascending tree: 1. if bit strings * have grown too large, quit. 2. if curr points to top * tree level, quit. */ if (hctree1[i].sort > MAX_BITLEN) { fprintf (stderr, "%s", catgets(dtsearch_catd, MS_huff, 30, "\n183 Bit strings have grown too large. You probably " "have literals\n turned off with grossly unbalanced " "character counts.\n\7")); exit (2); } if (hctree1[curr].count >= total_count) { fprintf (stderr, "%s", catgets(dtsearch_catd, MS_huff, 31, "\n191 Programming Error: Still trying to build\n" " Huffman Code Tree after root created.\n\7")); exit (2); } /* * if curr ptr already joins low0 or low1, try the next * table entry */ if (curr == low0 || curr == low1) continue; /* * If curr count is less than low0, or if curr count = low0 * but curr bitstring length is less, replace both low0 and * low1. (that way, we keep low0 always <= low1) */ if (low0 == -1 || hctree1[curr].count < hctree1[low0].count || (hctree1[curr].count == hctree1[low0].count && hctree1[i].sort < len0)) { low1 = low0; len1 = len0; low0 = curr; len0 = hctree1[i].sort; continue; } /* * At this point curr count is 'greater' than low0. If curr * count is less than low1, or if curr count = low1 but * curr bitstring length is less, replace only low1 */ if (low1 == -1 || hctree1[curr].count < hctree1[low1].count || (hctree1[curr].count == hctree1[low1].count && hctree1[i].sort < len1)) { low1 = curr; len1 = hctree1[i].sort; continue; } /* * default: curr count is greater than BOTH low0 and low1, * try next table entry */ } /* end loop to find two lowest counts */ /* low0 and low1 now point to two lowest count nodes. * link in low0 and low1 to next available new node. */ last_node++; hctree1[low0].bit = '0'; hctree1[low0].father = last_node; hctree1[low1].bit = '1'; hctree1[low1].father = last_node; hctree1[last_node].bit = LAST_BIT; hctree1[last_node].father = -1; hctree1[last_node].count = hctree1[low0].count + hctree1[low1].count; hctree1[last_node].son0 = low0; hctree1[last_node].son1 = low1; if (debug_switch) printf ("%3d: low0=%6ld\tlow1=%6ld\tsum=%6ld\t(%ld)\n", last_node, hctree1[low0].count, hctree1[low1].count, hctree1[last_node].count, total_count); if (hctree1[last_node].count < total_count) return TRUE; else return FALSE; } /* end of function build_tree */