static void add_file(struct cvs_file *cf) { int nb, stop; char revbuf[CVS_REV_BUFSZ]; RCSNUM *head = NULL; char *tag; cvs_parse_tagfile(cf->file_wd, &tag, NULL, &nb); if (nb) { cvs_log(LP_ERR, "cannot add file on non-branch tag %s", tag); return; } if (cf->file_rcs != NULL) { head = rcs_head_get(cf->file_rcs); if (head == NULL) { cvs_log(LP_NOTICE, "no head revision in RCS file for " "%s", cf->file_path); } rcsnum_tostr(head, revbuf, sizeof(revbuf)); } stop = 0; switch (cf->file_status) { case FILE_ADDED: case FILE_CHECKOUT: if (verbosity > 1) cvs_log(LP_NOTICE, "%s has already been entered", cf->file_path); stop = 1; break; case FILE_REMOVED: if (cf->file_rcs == NULL) { cvs_log(LP_NOTICE, "cannot resurrect %s; " "RCS file removed by second party", cf->file_name); } else if (!(cf->file_flags & FILE_ON_DISK)) { add_entry(cf); /* Restore the file. */ cvs_checkout_file(cf, head, NULL, 0); cvs_printf("U %s\n", cf->file_path); cvs_log(LP_NOTICE, "%s, version %s, resurrected", cf->file_name, revbuf); cf->file_status = FILE_UPTODATE; } stop = 1; break; case FILE_CONFLICT: case FILE_LOST: case FILE_MODIFIED: case FILE_UPTODATE: if (cf->file_rcs != NULL && cf->file_rcs->rf_dead == 0) { cvs_log(LP_NOTICE, "%s already exists, with version " "number %s", cf->file_path, revbuf); stop = 1; } break; case FILE_UNKNOWN: if (cf->file_rcs != NULL && cf->file_rcs->rf_dead == 1) { cvs_log(LP_NOTICE, "re-adding file %s " "(instead of dead revision %s)", cf->file_path, revbuf); added_files++; } else if (cf->file_flags & FILE_ON_DISK) { cvs_log(LP_NOTICE, "scheduling file '%s' for addition", cf->file_path); added_files++; } else { stop = 1; } break; default: break; } if (head != NULL) rcsnum_free(head); if (stop == 1) return; add_entry(cf); }
void cvs_history_add(int type, struct cvs_file *cf, const char *argument) { BUF *buf; FILE *fp; RCSNUM *hrev; size_t len; int fd; char *cwd, *p, *rev; char revbuf[CVS_REV_BUFSZ], repo[MAXPATHLEN], fpath[MAXPATHLEN]; char timebuf[CVS_TIME_BUFSZ]; struct tm datetm; if (cvs_nolog == 1) return; if (cvs_cmdop == CVS_OP_CHECKOUT || cvs_cmdop == CVS_OP_EXPORT) { if (type != CVS_HISTORY_CHECKOUT && type != CVS_HISTORY_EXPORT) return; } cvs_log(LP_TRACE, "cvs_history_add(`%c', `%s', `%s')", historytab[type], (cf != NULL) ? cf->file_name : "", argument); /* construct repository field */ if (cvs_cmdop != CVS_OP_CHECKOUT && cvs_cmdop != CVS_OP_EXPORT) { cvs_get_repository_name((cf != NULL) ? cf->file_wd : ".", repo, sizeof(repo)); } else { cvs_get_repository_name(argument, repo, sizeof(repo)); } if (cvs_server_active == 1) { cwd = "<remote>"; } else { if (getcwd(fpath, sizeof(fpath)) == NULL) fatal("cvs_history_add: getcwd: %s", strerror(errno)); p = fpath; if (cvs_cmdop == CVS_OP_CHECKOUT || cvs_cmdop == CVS_OP_EXPORT) { if (strlcat(fpath, "/", sizeof(fpath)) >= sizeof(fpath) || strlcat(fpath, argument, sizeof(fpath)) >= sizeof(fpath)) fatal("cvs_history_add: string truncation"); } if (cvs_homedir != NULL && cvs_homedir[0] != '\0') { len = strlen(cvs_homedir); if (strncmp(cvs_homedir, fpath, len) == 0 && fpath[len] == '/') { p += len - 1; *p = '~'; } } history_compress(p, repo); cwd = xstrdup(p); } /* construct revision field */ revbuf[0] = '\0'; rev = revbuf; switch (type) { case CVS_HISTORY_TAG: strlcpy(revbuf, argument, sizeof(revbuf)); break; case CVS_HISTORY_CHECKOUT: case CVS_HISTORY_EXPORT: /* * cvs_buf_alloc uses xcalloc(), so we are safe even * if neither cvs_specified_tag nor cvs_specified_date * have been supplied. */ buf = cvs_buf_alloc(128); if (cvs_specified_tag != NULL) { cvs_buf_puts(buf, cvs_specified_tag); if (cvs_specified_date != -1) cvs_buf_putc(buf, ':'); } if (cvs_specified_date != -1) { gmtime_r(&cvs_specified_date, &datetm); strftime(timebuf, sizeof(timebuf), "%Y.%m.%d.%H.%M.%S", &datetm); cvs_buf_puts(buf, timebuf); } rev = cvs_buf_release(buf); break; case CVS_HISTORY_UPDATE_MERGED: case CVS_HISTORY_UPDATE_MERGED_ERR: case CVS_HISTORY_COMMIT_MODIFIED: case CVS_HISTORY_COMMIT_ADDED: case CVS_HISTORY_COMMIT_REMOVED: case CVS_HISTORY_UPDATE_CO: if ((hrev = rcs_head_get(cf->file_rcs)) == NULL) fatal("cvs_history_add: rcs_head_get failed"); rcsnum_tostr(hrev, revbuf, sizeof(revbuf)); rcsnum_free(hrev); break; } (void)xsnprintf(fpath, sizeof(fpath), "%s/%s", current_cvsroot->cr_dir, CVS_PATH_HISTORY); if ((fd = open(fpath, O_WRONLY|O_APPEND)) == -1) { if (errno != ENOENT) cvs_log(LP_ERR, "failed to open history file"); } else { if ((fp = fdopen(fd, "a")) != NULL) { fprintf(fp, "%c%x|%s|%s|%s|%s|%s\n", historytab[type], time(NULL), getlogin(), cwd, repo, rev, (cf != NULL) ? cf->file_name : argument); (void)fclose(fp); } else { cvs_log(LP_ERR, "failed to add entry to history file"); (void)close(fd); } } if (rev != revbuf) xfree(rev); if (cvs_server_active != 1) xfree(cwd); }