get.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,050 行 · 第 1/2 页
C
1,050 行
#ifndef lintstatic char *sccsid = "@(#)get.c 4.2 (ULTRIX) 12/20/90";#endif lint/************************************************************************ * * * Copyright (c) 1984, 1988 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * * Modification history: * * 7 Dec 84 -- depp * Fix UID problem so that get forks a child to manipulate * files in user directory * 14 Dec 84 -- depp * Fixed the return from wait(), after fork/exec to manipulate g-file, * to handle the failure to manipulate the g-file. * * 07 Mar 88 -- map * Add -u option which sets the time of the g-file to the time of * the s-file. This results in a g-file with a time equal to the * last delta. This is useful for build scripts which extract * all files from the SCCS database and then do a make. * 28 Jun 88 -- D. Long * Use atomic rename operation in xremove instead of link and unlink. * Also don't use return value from fputs, Ultrix is not SVID * compliant here and returns undefined. Use ferror instead. * Also added error checking on output. */# include <sys/wait.h># include <time.h># include "../hdr/defines.h"# include "../hdr/had.h"struct stat Statbuf;struct timeval tv[2];char Null[1];char Error[128];int Debug = 0;int had_pfile;struct packet gpkt;struct sid sid;unsigned Ser;int num_files;char had[26];char Pfilename[FILESIZE];char *ilist, *elist, *lfile;char *sid_ab(), *auxf(), *logname();char *sid_ba(), *date_ba();long cutoff = 0X7FFFFFFFL; /* max positive long */int verbosity;char Gfile[FILESIZE];char *Type;int Did_id;FILE *fdfopen();/* Beginning of modifications made for CMF system. */#define CMRLIMIT 128char cmr[CMRLIMIT];int cmri = 0;/* End of insertion */main(argc,argv)int argc;register char *argv[];{ register int i; register char *p; char c; int testmore; extern int Fcnt; extern get(); Fflags = FTLEXIT | FTLMSG | FTLCLN; for(i=1; i<argc; i++) if(argv[i][0] == '-' && (c=argv[i][1])) { p = &argv[i][2]; testmore = 0; switch (c) { case CMFFLAG: /* Concatenate the rest of this argument with the * existing CMR list. */ while (*p) { if (cmri == CMRLIMIT) fatal ("CMR list is too long."); cmr[cmri++] = *p++; } cmr[cmri] = NULL; break; case 'a': if (!p[0]) { argv[i] = 0; continue; } Ser = patoi(p); break; case 'r': if (!p[0]) { argv[i] = 0; continue; } chksid(sid_ab(p,&sid),&sid); if ((sid.s_rel < MINR) || (sid.s_rel > MAXR)) fatal("r out of range (ge22)"); break; case 'c': if (!p[0]) { argv[i] = 0; continue; } if (date_ab(p,&cutoff)) fatal("bad date/time (cm5)"); break; case 'l': lfile = p; break; case 'i': if (!p[0]) { argv[i] = 0; continue; } ilist = p; break; case 'x': if (!p[0]) { argv[i] = 0; continue; } elist = p; break; case 'b': case 'g': case 'e': case 'p': case 'k': case 'm': case 'n': case 's': case 't': case 'u': testmore++; break; default: fatal("unknown key letter (cm1)"); } if (testmore) { testmore = 0; if (*p) { sprintf(Error, "value after %c arg (cm8)",c); fatal(Error); } } if (had[c - 'a']++) fatal("key letter twice (cm2)"); argv[i] = 0; } else num_files++; if(num_files == 0) fatal("missing file arg (cm3)"); if (HADE && HADM) fatal("e not allowed with m (ge3)"); if (HADE) HADK = 1; if (!HADS) verbosity = -1; if (HADE && ! logname()) fatal("User ID not in password file (cm9)"); setsig(); Fflags &= ~FTLEXIT; Fflags |= FTLJMP; for (i=1; i<argc; i++) if (p=argv[i]) do_file(p,get); exit(Fcnt ? 1 : 0);}extern char *Sflags[];get(file)char *file;{ register char *p; register unsigned ser; extern char had_dir, had_standinp; struct stats stats; struct idel *dodelt(); char str[32]; char *idsubst(), *auxf(); int i,status,holduid,holdgid; int retval; Fflags |= FTLMSG; if (setjmp(Fjmp)) return; if (HADE) { had_pfile = 1; /* call `sinit' to check if file is an SCCS file but don't open the SCCS file. If it is, then create lock file. */ sinit(&gpkt,file,0); if (lockit(auxf(file,'z'),10,getpid())) fatal("cannot create lock file (cm4)"); } /* Open SCCS file and initialize packet */ sinit(&gpkt,file,1); gpkt.p_ixuser = (HADI | HADX); gpkt.p_reqsid.s_rel = sid.s_rel; gpkt.p_reqsid.s_lev = sid.s_lev; gpkt.p_reqsid.s_br = sid.s_br; gpkt.p_reqsid.s_seq = sid.s_seq; gpkt.p_verbose = verbosity; gpkt.p_stdout = (HADP ? stderr : stdout); gpkt.p_cutoff = cutoff; gpkt.p_lfile = lfile; copy(auxf(gpkt.p_file,'g'),Gfile); if (gpkt.p_verbose && (num_files > 1 || had_dir || had_standinp)) fprintf(gpkt.p_stdout,"\n%s:\n",gpkt.p_file); if (dodelt(&gpkt,&stats,(struct sid *) 0,0) == 0) fmterr(&gpkt); finduser(&gpkt); doflags(&gpkt); if (!HADA) ser = getser(&gpkt); else { if ((ser = Ser) > maxser(&gpkt)) fatal("serial number too large (ge19)"); gpkt.p_gotsid = gpkt.p_idel[ser].i_sid; if (HADR && sid.s_rel != gpkt.p_gotsid.s_rel) { zero(&gpkt.p_reqsid, sizeof(gpkt.p_reqsid)); gpkt.p_reqsid.s_rel = sid.s_rel; } else gpkt.p_reqsid = gpkt.p_gotsid; } doie(&gpkt,ilist,elist,(char *) 0); setup(&gpkt,(int) ser); if((p = Sflags[LOCKGET - 'a'])) { retval = ck_lockget(p,&gpkt); if(retval) return(0); } if (!(Type = Sflags[TYPEFLAG - 'a'])) Type = Null; if (!(HADP || HADG)) if (exists(Gfile) && (S_IWRITE & Statbuf.st_mode)) { sprintf(Error,"writable `%s' exists (ge4)",Gfile); fatal(Error); } if (gpkt.p_verbose) { sid_ba(&gpkt.p_gotsid,str); fprintf(gpkt.p_stdout,"%s\n",str); } if (HADE) { if (HADC || gpkt.p_reqsid.s_rel == 0) gpkt.p_reqsid = gpkt.p_gotsid; newsid(&gpkt,Sflags[BRCHFLAG - 'a'] && HADB); permiss(&gpkt); if (exists(auxf(gpkt.p_file,'p'))) mk_qfile(&gpkt); else had_pfile = 0; wrtpfile(&gpkt,ilist,elist); } if (!HADG || HADL) { if (gpkt.p_stdout) fflush(gpkt.p_stdout); if (HADG) exit(0); /* fork a child to manipulate the g-file */ if ((i = fork()) < 0) fatal("Can not fork; try again"); if (i == 0) { setuid(getuid()); setgid(getgid()); if (HADL) gen_lfile(&gpkt); flushto(&gpkt,EUSERTXT,1); idsetup(&gpkt); gpkt.p_chkeof = 1; Did_id = 0; /* call `xcreate' which deletes the old `g-file' and creates a new one except if the `p' keyletter is set in which case any old `g-file' is not disturbed. The mod of the file depends on whether or not the `k' keyletter has been set. */ if (gpkt.p_gout == 0) { if (HADP) gpkt.p_gout = stdout; else gpkt.p_gout = xfcreat(Gfile,HADK ? 0644 : 0444); } while(readmod(&gpkt)) { prfx(&gpkt); p = idsubst(&gpkt,gpkt.p_line); fputs(p,gpkt.p_gout); if(ferror(gpkt.p_gout)) FAILPUT; } if (gpkt.p_gout) if(fflush(gpkt.p_gout)==EOF) FAILPUT; if (gpkt.p_gout && gpkt.p_gout != stdout) fclose(gpkt.p_gout); if (gpkt.p_verbose) fprintf(gpkt.p_stdout,"%u lines\n",gpkt.p_glnno); if (!Did_id && !HADK) if (Sflags[IDFLAG - 'a']) fatal("no id keywords (cm6)"); else if (gpkt.p_verbose) fprintf(stderr,"No id keywords (cm7)\n"); if (HADU) { exists(gpkt.p_file); tv[0].tv_sec = tv[1].tv_sec = Statbuf.st_mtime; tv[0].tv_usec = tv[1].tv_usec = 0; utimes(Gfile, tv); } exit(0); } else { wait(&status); if (status) { Fflags &= ~FTLMSG; fatal(); } } } if (gpkt.p_iop) fclose(gpkt.p_iop); /* remove 'q'-file because it is no longer needed */ unlink(auxf(gpkt.p_file,'q')); ffreeall(); unlockit(auxf(gpkt.p_file,'z'),getpid());}newsid(pkt,branch)register struct packet *pkt;int branch;{ int chkbr; chkbr = 0; /* if branch value is 0 set newsid level to 1 */ if (pkt->p_reqsid.s_br == 0) { pkt->p_reqsid.s_lev += 1; /* if the sid requested has been deltaed or the branch flag was set or the requested SID exists in the p-file then create a branch delta off of the gotten SID */ if (sidtoser(&pkt->p_reqsid,pkt) || pkt->p_maxr > pkt->p_reqsid.s_rel || branch || in_pfile(&pkt->p_reqsid,pkt)) { pkt->p_reqsid.s_rel = pkt->p_gotsid.s_rel; pkt->p_reqsid.s_lev = pkt->p_gotsid.s_lev; pkt->p_reqsid.s_br = pkt->p_gotsid.s_br + 1; pkt->p_reqsid.s_seq = 1; chkbr++; } } /* if a three component SID was given as the -r argument value and the b flag is not set then up the gotten SID sequence number by 1 */ else if (pkt->p_reqsid.s_seq == 0 && !branch) pkt->p_reqsid.s_seq = pkt->p_gotsid.s_seq + 1; else { /* if sequence number is non-zero then increment the requested SID sequence number by 1 */ pkt->p_reqsid.s_seq += 1; if (branch || sidtoser(&pkt->p_reqsid,pkt) || in_pfile(&pkt->p_reqsid,pkt)) { pkt->p_reqsid.s_br += 1; pkt->p_reqsid.s_seq = 1; chkbr++; } } /* keep checking the requested SID until a good SID to be made is calculated or all possibilities have been tried */ while (chkbr) { --chkbr; while (in_pfile(&pkt->p_reqsid,pkt)) { pkt->p_reqsid.s_br += 1; ++chkbr; } while (sidtoser(&pkt->p_reqsid,pkt)) { pkt->p_reqsid.s_br += 1; ++chkbr; } } if (sidtoser(&pkt->p_reqsid,pkt) || in_pfile(&pkt->p_reqsid,pkt)) fatal("bad SID calculated in newsid()");}enter(pkt,ch,n,sidp)struct packet *pkt;char ch;int n;struct sid *sidp;{ char str[32]; register struct apply *ap; sid_ba(sidp,str); if (pkt->p_verbose) fprintf(pkt->p_stdout,"%s\n",str); ap = &pkt->p_apply[n]; switch(ap->a_code) { case SX_EMPTY: if (ch == INCLUDE) condset(ap,APPLY,INCLUSER); else condset(ap,NOAPPLY,EXCLUSER); break; case APPLY: sid_ba(sidp,str); sprintf(Error,"%s already included (ge9)",str); fatal(Error); break; case NOAPPLY: sid_ba(sidp,str); sprintf(Error,"%s already excluded (ge10)",str); fatal(Error); break; default: fatal("internal error in get/enter() (ge11)"); break; }}gen_lfile(pkt)register struct packet *pkt;{ char *n; int reason; char str[32]; char line[BUFSIZ]; struct deltab dt; FILE *in; FILE *out; in = xfopen(pkt->p_file,0); if (*pkt->p_lfile) out = stdout; else out = xfcreat(auxf(pkt->p_file,'l'),0444); fgets(line,sizeof(line),in); while (fgets(line,sizeof(line),in) != NULL && line[0] == CTLCHAR && line[1] == STATS) { fgets(line,sizeof(line),in); del_ab(line,&dt,pkt); if (dt.d_type == 'D') { reason = pkt->p_apply[dt.d_serial].a_reason; if (pkt->p_apply[dt.d_serial].a_code == APPLY) { putc(' ',out); putc(' ',out); } else { putc('*',out); if (reason & IGNR) putc(' ',out); else putc('*',out); } switch (reason & (INCL | EXCL | CUTOFF)) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?