📄 installtxt.c
字号:
/* * Installtxt - installs and maintains archives of message strings * which are subsequently used by the gettext() utility. * Version of /usr/group proposal 12th Oct 88. * */#ifndef lintstatic char *sccsid = "@(#)installtxt.c 1.1 92/07/30 SMI";#endif not lint/* * installtxt. Utility to install and maintain archives of message * text. * If any of the message archive data structures change here * then they must change in gettext() also */#include <sys/param.h>#include <sys/stat.h>#include <sys/time.h>#include <locale.h>#include <signal.h>#include <stdio.h>#include <ctype.h>#include <sys/types.h>#include <sys/file.h>#include "gettext.h"#define ARMAG "!<LC_MESSAGES>\n"#define ARFMAG "`\n"#define SARMAG 15#define SKIP 1#define IODD 2#define OODD 4#define HEAD 8#define MAXTAGLEN 127#define MAXMSGLEN 255#define CMD_DOMAIN "domain"#define CMD_DOMAIN_LEN 6#define CMD_SEP "separator"#define CMD_SEP_LEN 9#define CMD_QUOTE "quote"#define CMD_QUOTE_LEN 5#define CMD_FORMAT "format"#define CMD_FORMAT_LEN 6#define BUFSIZE 512struct stat stbuf;struct ar_hdr arbuf;struct lar_hdr { unsigned char lar_name[16]; long lar_date; u_short lar_uid; u_short lar_gid; u_short lar_mode; long lar_size; unsigned char lar_sep; unsigned char lar_quote;} larbuf;char *man = { "cdrtx" };char *opt = { "ouv" };char linebuf[MAXTAGLEN+MAXMSGLEN+4];char message_tag[MAXTAGLEN+1];char message_text[MAXMSGLEN+1];char domain[MAXDOMAIN+1];char format[MAXFMTS+1] = "";short format_type;int countofrecords;long charsleft;char pattern[15] = "%[^ ]%*c%[^\n]";int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};int sigdone();long lseek();int rcmd();int dcmd();int xcmd();int tcmd();int ccmd();int (*comfun)();char flg[26];char **namv;int namc;char *arnam;char *tmpfnam = { "/tmp/vXXXXXX" };char *tmp1nam = { "/tmp/v1XXXXXX" };char *tmp2nam = { "/tmp/v2XXXXXX" };char *tfnam;char *tf1nam;char *tf2nam;char *file;char name[16];int af;int tf;int tf1;int tf2;int qf;int bastate;char buf[MAXBSIZE];int truncate; /* ok to truncate argument filenames */int cur_address;char *trim();char *mktemp();char *ctime();char *strncpy();/* This routine will fill up the output buffer pointed to by buff * with the escape expanded string, ready for human consumption * TODO : need notion of line length to do backslash-newline sequence * if necessary on output */short expandesc(buff, ch)char *buff; unsigned short ch; { switch (ch) { case '\n': *buff = '\\'; *(buff+1) = 'n'; return 2; case '\r': *buff = '\\'; *(buff+1) = 'r'; return 2; case '\b': *buff = '\\'; *(buff+1) = 'b'; return 2; case '\t': *buff = '\\'; *(buff+1) = 't'; return 2; case '\v': *buff = '\\'; *(buff+1) = 'v'; return 2; case '\f': *buff = '\\'; *(buff+1) = 'f'; return 2; case '\\': *buff = '\\'; *(buff+1) = '\\'; return 2; case '\'': *buff = '\\'; *(buff+1) = '\''; return 2; case '\"': *buff = '\\'; *(buff+1) = '\"'; return 2; default: *buff = ch; return 1; }}setcom(fun)int (*fun)();{ if(comfun != 0) { fprintf(stderr, "installtxt: only one of [%s] allowed\n", man); done(1); } comfun = fun;}rcmd(){ register f; truncate++; init(); getaf(); while(!getdir()) { if(namc == 0 || match()) { f = stats(); if(f < 0) { if(namc) fprintf(stderr, "installtxt: cannot open %s\n", file); goto cp; } if(flg['u'-'a']) if(stbuf.st_mtime <= larbuf.lar_date) { close(f); goto cp; } mesg('r'); copyfil(af, -1, SKIP); movefil(f); continue; } cp: mesg('c'); copyfil(af, tf, HEAD); } cleanup();}ccmd() { rcmd();}dcmd(){ init(); if(getaf()) noar(); while(!getdir()) { if(match()) { mesg('d'); copyfil(af, -1, SKIP); continue; } mesg('c'); copyfil(af, tf, HEAD); } install();}xcmd(){ register f; register short i; struct timeval tv[2]; unsigned char buf[10]; FILE *tempf; if(getaf()) noar(); while(!getdir()) { if(namc == 0 || match()) { f = open(file, O_RDWR | O_CREAT, larbuf.lar_mode & 0777); if(f < 0) { perror(file); goto sk; } mesg('x'); msg_extract(f); close(tf); close(f); if (flg['o'-'a']) { tv[0].tv_sec = tv[1].tv_sec = larbuf.lar_date; tv[0].tv_usec = tv[1].tv_usec = 0; utimes(file, tv); } continue; } sk: mesg('c'); copyfil(af, -1, SKIP); if (namc > 0 && !morefil()) done(0); }}tcmd(){ if(getaf()) noar(); while(!getdir()) { if(namc == 0 || match()) { if(flg['v'-'a']) longt(); printf("%s\n", trim(file, 0)); } copyfil(af, -1, SKIP); }}init(){ tfnam = mktemp(tmpfnam); close(creat(tfnam, 0600)); tf = open(tfnam, 2); if(tf < 0) { fprintf(stderr, "installtxt: cannot create temp file\n"); done(1); } if (write(tf, ARMAG, SARMAG) != SARMAG) wrerr();}getaf(){ char mbuf[SARMAG]; af = open(arnam, 0); if(af < 0) return(1); if (read(af, mbuf, SARMAG) != SARMAG || strncmp(mbuf, ARMAG, SARMAG)) { fprintf(stderr, "installtxt: %s not in message archive format\n", arnam); done(1); } return(0);}getqf(){ char mbuf[SARMAG]; if ((qf = open(arnam, 2)) < 0) { if(!flg['c'-'a']) fprintf(stderr, "installtxt: creating %s\n", arnam); if ((qf = creat(arnam, 0666)) < 0) { fprintf(stderr, "installtxt: cannot create %s\n", arnam); done(1); } if (write(qf, ARMAG, SARMAG) != SARMAG) wrerr(); } else if (read(qf, mbuf, SARMAG) != SARMAG || strncmp(mbuf, ARMAG, SARMAG)) { fprintf(stderr, "installtxt: %s not in message archive format\n", arnam); done(1); }} usage(){ fprintf(stderr, "usage: installtxt [%s][%s] source-message-files ...\n", man, opt); done(1);}noar(){ fprintf(stderr, "installtxt: %s does not exist\n", arnam); done(1);}sigdone(){ done(100);}done(c){ if(tfnam) unlink(tfnam); if(tf1nam) unlink(tf1nam); if(tf2nam) unlink(tf2nam); exit(c);}notfound(){ register i, n; n = 0; for(i=0; i<namc; i++) if(namv[i]) { fprintf(stderr, "installtxt: %s not found\n", namv[i]); n++; } return(n);}morefil(){ register i, n; n = 0; for(i=0; i<namc; i++) if(namv[i]) n++; return(n);}cleanup(){ register i, f; truncate++; for(i=0; i<namc; i++) { file = namv[i]; if(file == 0) continue; namv[i] = 0; mesg('a'); f = stats(); if(f < 0) { fprintf(stderr, "installtxt: %s cannot open\n", file); continue; } movefil(f); } install();}install(){ register i; for(i=0; signum[i]; i++) signal(signum[i], SIG_IGN); if(af < 0) if(!flg['c'-'a']) fprintf(stderr, "installtxt: creating %s\n", arnam); close(af); af = creat(arnam, 0666); if(af < 0) { fprintf(stderr, "installtxt: cannot create %s\n", arnam); done(1); } if(tfnam) { lseek(tf, 0l, 0); while((i = read(tf, buf, MAXBSIZE)) > 0) if (write(af, buf, i) != i) wrerr(); } if(tf2nam) { lseek(tf2, 0l, 0); while((i = read(tf2, buf, MAXBSIZE)) > 0) if (write(af, buf, i) != i) wrerr(); } if(tf1nam) { lseek(tf1, 0l, 0); while((i = read(tf1, buf, MAXBSIZE)) > 0) if (write(af, buf, i) != i) wrerr(); }}/* * insert the file 'file' * into the archive temporary file */movefil(f){ char buf[sizeof(arbuf)+1]; sprintf(buf, "%-16s%-12ld%-6u%-6u%-8o%-10ld%2c%1c%-2s", trim(file, 1), stbuf.st_mtime, (u_short)stbuf.st_uid, (u_short)stbuf.st_gid, stbuf.st_mode, stbuf.st_size, larbuf.lar_sep, larbuf.lar_quote, ARFMAG); memcpy((char *)&arbuf, buf, sizeof(arbuf)); larbuf.lar_size = stbuf.st_size; msg_build(f); /* Copy the new binary archive format into place in the archive file * keep old statistics as if the source file is being represented. */ close(f); }stats(){ register f; f = open(file, 0); if(f < 0) return(f); if(fstat(f, &stbuf) < 0) { close(f); return(-1); } return(f);}/* * copy next file * size given in arbuf */copyfil(fi, fo, flag){ register i, o; int pe; if(flag & HEAD) { for (i=sizeof(arbuf.ar_name)-1; i>=0; i--) { if (arbuf.ar_name[i]==' ') continue; else if (arbuf.ar_name[i]=='\0') arbuf.ar_name[i] = ' '; else break; } if (write(fo, (char *)&arbuf, sizeof arbuf) != sizeof arbuf) wrerr(); } pe = 0; while(larbuf.lar_size > 0) { i = o = MAXBSIZE; if(larbuf.lar_size < i) { i = o = larbuf.lar_size; if(i&1) { buf[i] = '\n'; if(flag & IODD) i++; if(flag & OODD) o++; } } if(read(fi, buf, i) != i) pe++; if((flag & SKIP) == 0) if (write(fo, buf, o) != o) wrerr(); larbuf.lar_size -= MAXBSIZE; } if(pe) phserr();}getdir(){ register unsigned char *cp; register i; i = read(af, (char *)&arbuf, sizeof arbuf); if(i != sizeof arbuf) { if(tf1nam) { i = tf; tf = tf1; tf1 = i; } return(1); } if (strncmp(arbuf.ar_fmag, ARFMAG, sizeof(arbuf.ar_fmag))) { fprintf(stderr, "installtxt: malformed message archive (at %ld)\n", lseek(af, 0L, 1)); done(1); } cp = arbuf.ar_name + sizeof(arbuf.ar_name); while (*--cp==' ') ; if (*cp == '/') *cp = '\0'; else *++cp = '\0'; strncpy(name, arbuf.ar_name, sizeof(arbuf.ar_name)); file = name; strncpy(larbuf.lar_name, name, sizeof(larbuf.lar_name)); sscanf(arbuf.ar_date, "%ld", &larbuf.lar_date); sscanf(arbuf.ar_uid, "%hd", &larbuf.lar_uid); sscanf(arbuf.ar_gid, "%hd", &larbuf.lar_gid); sscanf(arbuf.ar_mode, "%ho", &larbuf.lar_mode); sscanf(arbuf.ar_size, "%ld", &larbuf.lar_size); larbuf.lar_sep = arbuf.ar_sep; larbuf.lar_quote = arbuf.ar_quote; return(0);} match(){ register i; for(i=0; i<namc; i++) { if(namv[i] == 0) continue; if(strcmp(trim(namv[i], 0), file) == 0) { file = namv[i]; namv[i] = 0; return(1); } } return(0);}phserr(){ fprintf(stderr, "installtxt: phase error on %s\n", file);}mesg(c){ if(flg['v'-'a']) if(c != 'c' || flg['v'-'a'] > 1) printf("%c - %s\n", c, file);}char *trim(s, verb)char *s;{ register char *p1, *p2; static char trimmedname[sizeof(arbuf.ar_name)]; /* Strip trailing slashes */ for(p1 = s; *p1; p1++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -