int cvs_import(int argc, char **argv) { int i, ch; char repo[MAXPATHLEN], *arg = "."; struct cvs_recursion cr; struct trigger_list *line_list; while ((ch = getopt(argc, argv, cvs_cmd_import.cmd_opts)) != -1) { switch (ch) { case 'b': import_branch = optarg; break; case 'd': dflag = 1; break; case 'k': koptstr = optarg; kflag = rcs_kflag_get(koptstr); if (RCS_KWEXP_INVAL(kflag)) { cvs_log(LP_ERR, "invalid RCS keyword expansion mode"); fatal("%s", cvs_cmd_import.cmd_synopsis); } break; case 'm': logmsg = optarg; break; default: fatal("%s", cvs_cmd_import.cmd_synopsis); break; } } argc -= optind; argv += optind; if (argc < 3) fatal("%s", cvs_cmd_import.cmd_synopsis); import_repository = argv[0]; vendor_tag = argv[1]; argc -= 2; argv += 2; release_tags = argv; tagcount = argc; if (!rcs_sym_check(vendor_tag)) fatal("invalid symbol: %s", vendor_tag); for (i = 0; i < tagcount; i++) { if (!rcs_sym_check(release_tags[i])) fatal("invalid symbol: %s", release_tags[i]); } if (logmsg == NULL) { if (cvs_server_active) fatal("no log message specified"); else logmsg = cvs_logmsg_create(NULL, NULL, NULL, NULL); } if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) { cvs_client_connect_to_server(); cvs_client_send_request("Argument -b%s", IMPORT_DEFAULT_BRANCH); if (kflag) cvs_client_send_request("Argument -k%s", koptstr); cvs_client_send_logmsg(logmsg); cvs_client_send_request("Argument %s", import_repository); cvs_client_send_request("Argument %s", vendor_tag); for (i = 0; i < tagcount; i++) cvs_client_send_request("Argument %s", release_tags[i]); cr.enterdir = NULL; cr.leavedir = NULL; cr.fileproc = cvs_client_sendfile; cr.flags = CR_RECURSE_DIRS; cvs_file_run(1, &arg, &cr); cvs_client_senddir("."); cvs_client_send_request("import"); cvs_client_get_responses(); return (0); } if (cvs_logmsg_verify(logmsg)) return (0); (void)xsnprintf(repo, sizeof(repo), "%s/%s", current_cvsroot->cr_dir, import_repository); import_loginfo(import_repository); if (cvs_noexec != 1) cvs_mkdir(repo, 0755); cr.enterdir = NULL; cr.leavedir = NULL; cr.fileproc = cvs_import_local; cr.flags = CR_RECURSE_DIRS; cvs_file_run(1, &arg, &cr); if (import_conflicts != 0) { import_printf("\n%d conflicts created by this import.\n\n", import_conflicts); import_printf("Use the following command to help the merge:\n"); import_printf("\topencvs checkout "); import_printf("-j%s:yesterday -j%s %s\n\n", vendor_tag, vendor_tag, import_repository); } else { import_printf("\nNo conflicts created by this import.\n\n"); } loginfo = buf_release(logbuf); logbuf = NULL; line_list = cvs_trigger_getlines(CVS_PATH_LOGINFO, import_repository); if (line_list != NULL) { cvs_trigger_handle(CVS_TRIGGER_LOGINFO, import_repository, loginfo, line_list, NULL); cvs_trigger_freelist(line_list); } xfree(loginfo); return (0); }
struct trigger_list * cvs_trigger_getlines(char * file, char * repo) { FILE *fp; int allow_all, lineno, match = 0; size_t len; regex_t preg; struct trigger_list *list; struct trigger_line *tline; char fpath[PATH_MAX]; char *currentline, *defaultline = NULL, *nline, *p, *q, *regex; if (strcmp(file, CVS_PATH_EDITINFO) == 0 || strcmp(file, CVS_PATH_VERIFYMSG) == 0) allow_all = 0; else allow_all = 1; (void)xsnprintf(fpath, PATH_MAX, "%s/%s", current_cvsroot->cr_dir, file); if ((fp = fopen(fpath, "r")) == NULL) { if (errno != ENOENT) cvs_log(LP_ERRNO, "cvs_trigger_getlines: %s", file); return (NULL); } list = xmalloc(sizeof(*list)); TAILQ_INIT(list); lineno = 0; nline = NULL; while ((currentline = fgetln(fp, &len)) != NULL) { if (currentline[len - 1] == '\n') { currentline[len - 1] = '\0'; } else { nline = xmalloc(len + 1); memcpy(nline, currentline, len); nline[len] = '\0'; currentline = nline; } lineno++; for (p = currentline; isspace((unsigned char)*p); p++) ; if (*p == '\0' || *p == '#') continue; for (q = p; !isspace((unsigned char)*q) && *q != '\0'; q++) ; if (*q == '\0') goto bad; *q++ = '\0'; regex = p; for (; isspace((unsigned char)*q); q++) ; if (*q == '\0') goto bad; if (strcmp(regex, "ALL") == 0 && allow_all) { tline = xmalloc(sizeof(*tline)); tline->line = xstrdup(q); TAILQ_INSERT_TAIL(list, tline, flist); } else if (defaultline == NULL && !match && strcmp(regex, "DEFAULT") == 0) { defaultline = xstrdup(q); } else if (!match) { if (regcomp(&preg, regex, REG_NOSUB|REG_EXTENDED)) goto bad; if (regexec(&preg, repo, 0, NULL, 0) != REG_NOMATCH) { match = 1; tline = xmalloc(sizeof(*tline)); tline->line = xstrdup(q); TAILQ_INSERT_HEAD(list, tline, flist); } regfree(&preg); } } free(nline); if (defaultline != NULL) { if (!match) { tline = xmalloc(sizeof(*tline)); tline->line = defaultline; TAILQ_INSERT_HEAD(list, tline, flist); } else free(defaultline); } (void)fclose(fp); if (TAILQ_EMPTY(list)) { free(list); list = NULL; } return (list); bad: cvs_log(LP_NOTICE, "%s: malformed line %d", file, lineno); free(defaultline); cvs_trigger_freelist(list); (void)fclose(fp); return (NULL); }
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; }