📄 ci.c
字号:
targetdelta=nil; ffree(); switch (pairfilenames(argc, argv, rcswriteopen, false, false)) { case -1: /* New RCS file */# if has_setuid && has_getuid if (euid() != ruid()) { error("setuid initial checkin prohibited; use `rcs -i -a' first"); continue; }# endif rcsinitflag = true; break; case 0: /* Error */ continue; case 1: /* Normal checkin with prev . RCS file */ rcsinitflag = !Head; } /* now RCSfilename contains the name of the RCS file, and * workfilename contains the name of the working file. * If the RCS file exists, finptr contains the file descriptor for the * RCS file. The admin node is initialized. * RCSstat is set. */ diagnose("%s <-- %s\n", RCSfilename,workfilename); if (!(workptr = Iopen(workfilename, FOPEN_R_WORK, &workstat))) { eerror(workfilename); continue; } if (finptr && !checkaccesslist()) continue; /* give up */ krev = rev; if (keepflag) { /* get keyword values from working file */ if (!getoldkeys(workptr)) continue; if (!rev && !*(krev = prevrev.string)) { error("can't find a revision number in %s",workfilename); continue; } if (!*prevdate.string && *altdate=='\0' && usestatdate==false) warn("can't find a date in %s", workfilename); if (!*prevauthor.string && !author) warn("can't find an author in %s", workfilename); if (!*prevstate.string && !state) warn("can't find a state in %s", workfilename); } /* end processing keepflag */ /* Read the delta tree. */ if (finptr) gettree(); /* expand symbolic revision number */ if (!fexpandsym(krev, &newdelnum, workptr)) continue; /* splice new delta into tree */ if ((removedlock = addelta()) < 0) continue; newdelta.num = newdelnum.string; newdelta.branches=nil; newdelta.lockedby=nil; /*might be changed by addlock() */ newdelta.selector = true; /* set author */ if (author!=nil) newdelta.author=author; /* set author given by -w */ else if (keepflag && *prevauthor.string) newdelta.author=prevauthor.string; /* preserve old author if possible*/ else newdelta.author=getcaller();/* otherwise use caller's id */ newdelta.state = default_state; if (state!=nil) newdelta.state=state; /* set state given by -s */ else if (keepflag && *prevstate.string) newdelta.state=prevstate.string; /* preserve old state if possible */ if (usestatdate) { time2date(workstat.st_mtime, altdate); } if (*altdate!='\0') newdelta.date=altdate; /* set date given by -d */ else if (keepflag && *prevdate.string) { /* Preserve old date if possible. */ str2date(prevdate.string, olddate); newdelta.date = olddate; } else newdelta.date = getcurdate(); /* use current date */ /* now check validity of date -- needed because of -d and -k */ if (targetdelta!=nil && cmpnum(newdelta.date,targetdelta->date) < 0) { error("Date %s precedes %s in existing revision %s.", date2str(newdelta.date, newdatebuf), date2str(targetdelta->date, targetdatebuf), targetdelta->num ); continue; } if (lockflag && addlock(&newdelta) < 0) continue; if (!addsyms(newdelta.num)) continue; putadmin(frewrite); puttree(Head,frewrite); putdesc(false,textfile); changework = Expand != OLD_EXPAND; lockthis = lockflag; workdelta = &newdelta; /* build rest of file */ if (rcsinitflag) { diagnose("initial revision: %s\n", newdelnum.string); /* get logmessage */ newdelta.log=getlogmsg(); if (!putdftext(newdelnum.string,newdelta.log,workptr,frewrite,false)) continue; RCSstat.st_mode = workstat.st_mode; changedRCS = true; } else { diffilename = maketemp(0); workdiffname = workfilename; if (workdiffname[0] == '+') { /* Some diffs have options with leading '+'. */ char *dp = ftnalloc(char, strlen(workfilename)+3); workdiffname = dp; *dp++ = '.'; *dp++ = SLASH; VOID strcpy(dp, workfilename); } newhead = Head == &newdelta; if (!newhead) foutptr = frewrite; expfilename = buildrevision( gendeltas, targetdelta, (FILE*)0, false ); if ( !forceciflag && (changework = rcsfcmp( workptr, &workstat, expfilename, targetdelta )) <= 0 ) { diagnose("file is unchanged; reverting to previous revision %s\n", targetdelta->num ); if (removedlock < lockflag) { diagnose("previous revision was not locked; ignoring -l option\n"); lockthis = 0; } if (!(changedRCS = lockflag < removedlock || assoclst || newdelta.state != default_state && strcmp(newdelta.state, targetdelta->state) != 0 )) workdelta = targetdelta; else { /* * We have started to build the wrong new RCS file. * Start over from the beginning. */ long hwm = ftell(frewrite); int bad_truncate; if (fseek(frewrite, 0L, SEEK_SET) != 0) Oerror();# if !has_ftruncate bad_truncate = 1;# else /* * Work around a common ftruncate() bug. * We can't rely on has_truncate, because we might * be using a filesystem exported to us via NFS. */ bad_truncate = ftruncate(fileno(frewrite),(off_t)0); if (bad_truncate && errno != EACCES) Oerror();# endif Irewind(finptr); Lexinit(); getadmin(); gettree(); if (!(workdelta = genrevs( targetdelta->num, (char*)0, (char*)0, (char*)0, &gendeltas ))) continue; workdelta->log = targetdelta->log; if (newdelta.state != default_state) workdelta->state = newdelta.state; if (removedlock && removelock(workdelta)<0) continue; if (!addsyms(workdelta->num)) continue; if (!dorewrite(true, true)) continue; fastcopy(finptr, frewrite); if (bad_truncate) while (ftell(frewrite) < hwm) /* White out any earlier mistake with '\n's. */ /* This is unlikely. */ afputc('\n', frewrite); } } else { diagnose("new revision: %s; previous revision: %s\n", newdelnum.string, targetdelta->num ); newdelta.log = getlogmsg(); switch (run((char*)0, diffilename, DIFF DIFF_FLAGS, newhead ? workdiffname : expfilename, newhead ? expfilename : workdiffname, (char*)0 )) { case DIFF_FAILURE: case DIFF_SUCCESS: break; default: faterror("diff failed"); } if (newhead) { Irewind(workptr); if (!putdftext(newdelnum.string,newdelta.log,workptr,frewrite,false)) continue; if (!putdtext(targetdelta->num,targetdelta->log,diffilename,frewrite,true)) continue; } else if (!putdtext(newdelnum.string,newdelta.log,diffilename,frewrite,true)) continue; changedRCS = true; } } if (!donerewrite(changedRCS)) continue; if (!keepworkingfile) { Izclose(&workptr); r = un_link(workfilename); /* Get rid of old file */ } else { newworkmode = WORKMODE(RCSstat.st_mode, ! (Expand==VAL_EXPAND || lockthis < StrictLocks) ); mtime = mtimeflag ? workdelta->date : (char const*)0; /* Expand if it might change or if we can't fix mode, time. */ if (changework || (r=fixwork(newworkmode,mtime)) != 0) { Irewind(workptr); /* Expand keywords in file. */ locker_expansion = lockthis; switch (xpandfile( workptr, workfilename, workdelta, &newworkfilename )) { default: continue; case 0: /* * No expansion occurred; try to reuse working file * unless we already tried and failed. */ if (changework) if ((r=fixwork(newworkmode,mtime)) == 0) break; /* fall into */ case 1: if (!(r = setfiledate(newworkfilename,mtime))) { Izclose(&workptr); ignoreints(); r = chnamemod(&exfile, newworkfilename, workfilename, newworkmode); keepdirtemp(newworkfilename); restoreints(); } } } } if (r != 0) { eerror(workfilename); continue; } diagnose("done\n"); } while (cleanup(), ++argv, --argc >=1); tempunlink(); exitmain(exitstatus);} /* end of main (ci) */ static voidcleanup(){ if (nerror) exitstatus = EXIT_FAILURE; Izclose(&finptr); Izclose(&workptr); Ozclose(&exfile); Ozclose(&fcopy); Ozclose(&frewrite); dirtempunlink();}#if lint# define exiterr ciExit#endif exiting voidexiterr(){ dirtempunlink(); tempunlink(); _exit(EXIT_FAILURE);}/*****************************************************************//* the rest are auxiliary routines */ static intaddelta()/* Function: Appends a delta to the delta tree, whose number is * given by newdelnum. Updates Head, newdelnum, newdelnumlength, * and the links in newdelta. * Return -1 on error, 1 if a lock is removed, 0 otherwise. */{ register char *tp; register unsigned i; int removedlock; unsigned newdnumlength; /* actual length of new rev. num. */ newdnumlength = countnumflds(newdelnum.string); if (rcsinitflag) { /* this covers non-existing RCS file and a file initialized with rcs -i */ if ((newdnumlength==0)&&(Dbranch!=nil)) { bufscpy(&newdelnum, Dbranch); newdnumlength = countnumflds(Dbranch); } if (newdnumlength==0) bufscpy(&newdelnum, "1.1"); else if (newdnumlength==1) bufscat(&newdelnum, ".1"); else if (newdnumlength>2) { error("Branch point doesn't exist for %s.",newdelnum.string); return -1; } /* newdnumlength == 2 is OK; */ Head = &newdelta; newdelta.next=nil; return 0; } if (newdnumlength==0) { /* derive new revision number from locks */ switch (findlock(true, &targetdelta)) { default: /* found two or more old locks */ return -1; case 1: /* found an old lock */ /* check whether locked revision exists */ if (!genrevs(targetdelta->num,(char*)0,(char*)0,(char*)0,&gendeltas)) return -1; if (targetdelta==Head) { /* make new head */ newdelta.next=Head; Head= &newdelta; } else if (!targetdelta->next && countnumflds(targetdelta->num)>2) { /* new tip revision on side branch */ targetdelta->next= &newdelta; newdelta.next = nil; } else { /* middle revision; start a new branch */ bufscpy(&newdelnum, ""); return addbranch(targetdelta,&newdelnum); } incnum(targetdelta->num, &newdelnum); return 1; /* successful use of existing lock */ case 0: /* no existing lock; try Dbranch */ /* update newdelnum */ if (StrictLocks || !myself(RCSstat.st_uid)) { error("no lock set by %s",getcaller()); return -1; } if (Dbranch) { bufscpy(&newdelnum, Dbranch); } else { incnum(Head->num, &newdelnum); } newdnumlength = countnumflds(newdelnum.string); /* now fall into next statement */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -