static void add_directory(struct cvs_file *cf) { int added, nb; struct stat st; CVSENTRIES *entlist; char *date, entry[MAXPATHLEN], msg[1024], repo[MAXPATHLEN], *tag, *p; struct file_info_list files_info; struct file_info *fi; struct trigger_list *line_list; cvs_log(LP_TRACE, "add_directory(%s)", cf->file_path); (void)xsnprintf(entry, MAXPATHLEN, "%s%s", cf->file_rpath, RCS_FILE_EXT); added = 1; if (stat(entry, &st) != -1) { cvs_log(LP_NOTICE, "cannot add directory %s: " "a file with that name already exists", cf->file_path); added = 0; } else { /* Let's see if we have any per-directory tags first. */ cvs_parse_tagfile(cf->file_wd, &tag, &date, &nb); (void)xsnprintf(entry, MAXPATHLEN, "%s/%s", cf->file_path, CVS_PATH_CVSDIR); if (cvs_server_active) { if (mkdir(cf->file_rpath, 0755) == -1 && errno != EEXIST) fatal("add_directory: %s: %s", cf->file_rpath, strerror(errno)); } else if (stat(entry, &st) != -1) { if (!S_ISDIR(st.st_mode)) { cvs_log(LP_ERR, "%s exists but is not " "directory", entry); } else { cvs_log(LP_NOTICE, "%s already exists", entry); } added = 0; } else if (cvs_noexec != 1) { if (mkdir(cf->file_rpath, 0755) == -1 && errno != EEXIST) fatal("add_directory: %s: %s", cf->file_rpath, strerror(errno)); cvs_get_repository_name(cf->file_wd, repo, MAXPATHLEN); (void)xsnprintf(entry, MAXPATHLEN, "%s/%s", repo, cf->file_name); cvs_mkadmin(cf->file_path, current_cvsroot->cr_dir, entry, tag, date); p = xmalloc(CVS_ENT_MAXLINELEN); cvs_ent_line_str(cf->file_name, NULL, NULL, NULL, NULL, 1, 0, p, CVS_ENT_MAXLINELEN); entlist = cvs_ent_open(cf->file_wd); cvs_ent_add(entlist, p); xfree(p); } } if (added == 1 && current_cvsroot->cr_method == CVS_METHOD_LOCAL) { (void)xsnprintf(msg, sizeof(msg), "Directory %s added to the repository", cf->file_rpath); if (tag != NULL) { (void)strlcat(msg, "\n--> Using per-directory sticky tag ", sizeof(msg)); (void)strlcat(msg, tag, sizeof(msg)); } if (date != NULL) { (void)strlcat(msg, "\n--> Using per-directory sticky date ", sizeof(msg)); (void)strlcat(msg, date, sizeof(msg)); } cvs_printf("%s\n", msg); if (tag != NULL) xfree(tag); if (date != NULL) xfree(date); cvs_get_repository_name(cf->file_path, repo, MAXPATHLEN); line_list = cvs_trigger_getlines(CVS_PATH_LOGINFO, repo); if (line_list != NULL) { TAILQ_INIT(&files_info); fi = xcalloc(1, sizeof(*fi)); fi->file_path = xstrdup(cf->file_path); TAILQ_INSERT_TAIL(&files_info, fi, flist); cvs_add_loginfo(repo); cvs_trigger_handle(CVS_TRIGGER_LOGINFO, repo, loginfo, line_list, &files_info); cvs_trigger_freeinfo(&files_info); cvs_trigger_freelist(line_list); if (loginfo != NULL) xfree(loginfo); } } cf->file_status = FILE_SKIP; }
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); }