int search_paths(t_env *e) { t_search env; env.paths = ft_strsplit(ft_getenv("PATH", e), ':'); env.y = 0; while (env.y > -1 && env.paths[env.y] != 0) { env.dirp = opendir(env.paths[env.y]); while ((env.entry = readdir(env.dirp)) != NULL) { if (strcmp(env.entry->d_name, e->args[0]) == 0) { env.str = ft_strjoin(env.paths[env.y], "/"); run_exec(ft_strjoin(env.str, env.entry->d_name), e); free(env.str); env.str = NULL; env.y = -2; } } closedir(env.dirp); env.y++; } free_tab(env.paths); free(env.paths); env.paths = NULL; return (env.y); }
static HRESULT RegExp_exec(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { match_state_t *match; heap_pool_t *mark; BOOL b; jsstr_t *string; HRESULT hres; TRACE("\n"); mark = heap_pool_mark(&ctx->tmp_heap); hres = run_exec(ctx, jsthis, argc ? argv[0] : jsval_string(jsstr_empty()), &string, &match, &b); if(FAILED(hres)) { heap_pool_clear(mark); return hres; } if(r) { if(b) { IDispatch *ret; hres = create_match_array(ctx, string, match, &ret); if(SUCCEEDED(hres)) *r = jsval_disp(ret); }else { *r = jsval_null(); } } heap_pool_clear(mark); jsstr_release(string); return hres; }
/* ***************************************************************************** ** FUNCTION NAME: charset_detect ** ** FUNCTION INPUTS: ** @char *buf: The buffer will be detect ** @int len: buffer size. ** ** FUNCTION DESCRIPTION ** This function will detect buffer charset by zchardet. ** ** FUNCTION OUTPUTS: ** Returns NULL when failed or Utf-8 format. Return format. ** ** HISTORY: ** 2008-7-15 Steven Leong Created ***************************************************************************** */ static char* charset_detect(char *buf, int len) { int wfd, rfd, pid; fd_set rdfds; struct timeval tv; char bufArray[BUF_256_BITS] = {0}; FILE * ptrPipe = NULL; char cmdArray[BUF_512_BITS] = {0}; int n, nRet = -1; dprintf("ZChartDet Request(%d) -> %s\n", len, buf); /* start the zdev bin */ if( (pid = run_exec(ZCHAR_DETECT, &wfd, &rfd)) <= 0 ) { return NULL; } /* send cmd */ if( write_pipe (wfd, buf, len, 5) <= 0 ) { goto errOut; } FD_ZERO (&rdfds); FD_SET (rfd, &rdfds); tv.tv_sec = ZCHAR_DETECT_TIMEOUT; tv.tv_usec = 0; select (rfd+1, &rdfds, NULL, NULL, &tv); if(FD_ISSET (rfd, &rdfds)){ n = read(rfd, bufArray, BUF_256_BITS); bufArray[n] = '\0'; if(n < 0){ /* error or EAGAIN */ goto errOut; } } else{ /* timeout */ goto errOut; } nRet = 0; dprintf("ZChartDet Response -> %s\n", bufArray); errOut: /* kill pid */ /* 080129, JC, force kill bin */ sprintf(cmdArray, "kill -9 %d", pid); ptrPipe = popen(cmdArray, "r"); if (ptrPipe) { pclose(ptrPipe); } //kill(pid, SIGKILL); /* end force kill */ if (waitpid(pid, NULL, 0) != pid) fprintf(stderr, "Waitpid child error"); close(wfd); close(rfd); if(nRet == 0 || strlen(bufArray) > 0) return strdup(bufArray); return NULL; }
//************************************************************************** // function to parse/manage/execute commands //************************************************************************** void manager(command_t* cmd ){ char* temp [MAX_COMMAND_LENGTH]; strcpy(temp, cmd->cmdstr); char* tokens = strtok(temp, " "); //cd if the first two chars are cd if (!strcmp(tokens, "cd")){ run_cd( tokens ); } //set else if (!strcmp(tokens, "set")){ run_set( tokens); } //echo else if (!strcmp(tokens, "echo")){ run_echo( tokens ); } //pwd else if (!strcmp(tokens, "pwd")){ run_pwd( tokens ); } //jobs else if (!strcmp(tokens, "jobs")){ run_jobs( cmd, tokens ); } //exit command else if (!strcmp(tokens, "exit") || !strcmp(tokens, "quit") ) terminate(); // Exit Quash //run an executable else{ run_exec(cmd, tokens); } }
static int gencontrol(struct source_control *c) { struct source_control_bin *sb; char *out_control; char *argv[] = { "gencontrol", "-v", version, "-o", NULL, control_path, NULL, NULL, }; if (out_dir == NULL) { fprintf(stderr, "gencontrol: out dir must be set\n"); return -1; } for (sb = c->bins; sb != NULL; sb = sb->next) { if (asprintf(&out_control, "%s/%s/packages/%s/%s/control", work_dir, out_dir, sb->package, version) == -1) { perror("gencontrol: asprintf failed"); return -1; } argv[6] = sb->package; argv[4] = out_control; if (run_exec(argv) != 0) { fprintf(stderr, "gencontrol: running for %s failed\n", sb->package); free(out_control); return -1; } free(out_control); } return 0; }
static int unpack(struct source_control *c) { struct control_source *cs; int distd_fd, workd_fd; int ret = 0, r; char *unpack_argv[] = { "./unpack.sh", NULL }; if (dist_dir == NULL) { fprintf(stderr, "unpack: dist dir must be set\n"); return -1; } if ((distd_fd = open(dist_dir, O_RDONLY | O_DIRECTORY)) == -1) { perror("unpack: open distdir failed"); return -1; } if ((workd_fd = open(work_dir, O_RDONLY | O_DIRECTORY)) == -1) { perror("unpack: open workdir failed"); ret = -1; goto error_close_dist; } /* copying distfiles */ for (cs = c->sources; cs != NULL; cs = cs->next) { if (copy_file(distd_fd, cs->source, workd_fd, cs->source) != 0) { fprintf(stderr, "unpack: copying source %s failed\n", cs->source); ret = -1; goto error_close_work; } } /* run unpack script */ if (pkg_dir == NULL) { r = run_exec(unpack_argv); } else { r = run_exec_env(unpack_argv, c->unpack_depend); } if (r != 0) { fprintf(stderr, "unpack: running unpack script failed\n"); ret = -1; goto error_close_work; } error_close_work: close(workd_fd); error_close_dist: close(distd_fd); return ret; }
static int build(struct source_control *c) { int ret; char *outdir; char *build_argv[] = { "./build.sh", NULL }; (void) c; if (out_dir == NULL) { fprintf(stderr, "build: out dir must be set\n"); return -1; } /* run build script */ if (pkg_dir == NULL) { if (asprintf(&outdir, "%s/%s", work_dir, out_dir) == -1) { perror("build: asprintf failed"); return -1; } ret = setenv("PKG_INSTDIR", outdir, 1); free(outdir); if (ret != 0) { perror("build: setting PKG_INSTDIR failed"); return -1; } ret = run_exec(build_argv); } else { if (asprintf(&outdir, "/work/%s", out_dir) == -1) { perror("build: asprintf failed"); return -1; } ret = setenv("PKG_INSTDIR", outdir, 1); free(outdir); if (ret != 0) { perror("build: setting PKG_INSTDIR failed"); return -1; } ret = run_exec_env(build_argv, c->build_depend); } if (ret != 0) { fprintf(stderr, "build: running build script failed\n"); return -1; } return 0; }
/* * callback proc to run a script when admin finishes. */ static int postadmin_proc (const char *repository, const char *filter, void *closure) { char *cmdline; const char *srepos = Short_Repository (repository); TRACE (TRACE_FUNCTION, "postadmin_proc (%s, %s)", repository, filter); /* %c = cvs_cmd_name * %R = referrer * %p = shortrepos * %r = repository */ /* * Cast any NULL arguments as appropriate pointers as this is an * stdarg function and we need to be certain the caller gets what * is expected. */ cmdline = format_cmdline ( #ifdef SUPPORT_OLD_INFO_FMT_STRINGS false, srepos, #endif /* SUPPORT_OLD_INFO_FMT_STRINGS */ filter, "c", "s", cvs_cmd_name, #ifdef SERVER_SUPPORT "R", "s", referrer ? referrer->original : "NONE", #endif /* SERVER_SUPPORT */ "p", "s", srepos, "r", "s", current_parsed_root->directory, (char *) NULL); if (!cmdline || !strlen (cmdline)) { if (cmdline) free (cmdline); error (0, 0, "postadmin proc resolved to the empty string!"); return 1; } run_setup (cmdline); free (cmdline); /* FIXME - read the comment in verifymsg_proc() about why we use abs() * below() and shouldn't. */ return abs (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL | RUN_SIGIGNORE)); }
static int run_exec_env(char *script[], struct control_dependency *deps) { struct control_dependency *cd; int n, k, r; char **argv; /* count args */ for (k = 0; script[k] != NULL; k++); /* counting dependencies */ for (n = 0, cd = deps; cd != NULL; cd = cd->next, n++); /* newns withpkgs + -d DIR + n * (-d PKG) + -w WORK -c /work * -- k + NULL */ if ((argv = calloc(2 + 2 + 2 * n + 2 + 5 + k + 1, sizeof(*argv))) == NULL) { perror("run_exec_env: malloc failed"); return -1; } n = 0; argv[n++] = "newns"; argv[n++] = "withpkgs"; argv[n++] = "-d"; argv[n++] = pkg_dir; for (cd = deps; cd != NULL; cd = cd->next) { argv[n++] = "-p"; argv[n++] = cd->package; } argv[n++] = "-w"; argv[n++] = work_dir; argv[n++] = "-c"; argv[n++] = "/work"; for (k = 0; script[k] != NULL; k++) argv[n++] = script[k]; argv[n++] = NULL; r = run_exec(argv); free(argv); return r; }
static HRESULT RegExp_test(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { match_state_t *match; jsstr_t *undef_str; heap_pool_t *mark; BOOL b; HRESULT hres; TRACE("\n"); mark = heap_pool_mark(&ctx->tmp_heap); hres = run_exec(ctx, jsthis, argc ? argv[0] : jsval_string(undef_str = jsstr_undefined()), NULL, &match, &b); heap_pool_clear(mark); if(!argc) jsstr_release(undef_str); if(FAILED(hres)) return hres; if(r) *r = jsval_bool(b); return S_OK; }
/* * Builds a temporary file using setup_tmpfile() and invokes the user's * editor on the file. The header garbage in the resultant file is then * stripped and the log message is stored in the "message" argument. * * If REPOSITORY is non-NULL, process rcsinfo for that repository; if it * is NULL, use the CVSADM_TEMPLATE file instead. REPOSITORY should be * NULL when running in client mode. * * GLOBALS * Editor Set to a default value by configure and overridable using the * -e option to the CVS executable. */ void do_editor (const char *dir, char **messagep, const char *repository, List *changes) { static int reuse_log_message = 0; char *line; int line_length; size_t line_chars_allocated; char *fname; struct stat pre_stbuf, post_stbuf; int retcode = 0; assert (!current_parsed_root->isremote != !repository); if (noexec || reuse_log_message) return; /* Abort before creation of the temp file if no editor is defined. */ if (strcmp (Editor, "") == 0) error(1, 0, "no editor defined, must use -e or -m"); again: /* Create a temporary file. */ if( ( fp = cvs_temp_file( &fname ) ) == NULL ) error( 1, errno, "cannot create temporary file" ); if (*messagep) { (void) fputs (*messagep, fp); if ((*messagep)[0] == '\0' || (*messagep)[strlen (*messagep) - 1] != '\n') (void) fprintf (fp, "\n"); } else (void) fprintf (fp, "\n"); if (repository != NULL) /* tack templates on if necessary */ (void) Parse_Info (CVSROOTADM_RCSINFO, repository, rcsinfo_proc, PIOPT_ALL, NULL); else { FILE *tfp; char buf[1024]; size_t n; size_t nwrite; /* Why "b"? */ tfp = CVS_FOPEN (CVSADM_TEMPLATE, "rb"); if (tfp == NULL) { if (!existence_error (errno)) error (1, errno, "cannot read %s", CVSADM_TEMPLATE); } else { while (!feof (tfp)) { char *p = buf; n = fread (buf, 1, sizeof buf, tfp); nwrite = n; while (nwrite > 0) { n = fwrite (p, 1, nwrite, fp); nwrite -= n; p += n; } if (ferror (tfp)) error (1, errno, "cannot read %s", CVSADM_TEMPLATE); } if (fclose (tfp) < 0) error (0, errno, "cannot close %s", CVSADM_TEMPLATE); } } (void) fprintf (fp, "%s----------------------------------------------------------------------\n", CVSEDITPREFIX); (void) fprintf (fp, "%sEnter Log. Lines beginning with `%.*s' are removed automatically\n%s\n", CVSEDITPREFIX, CVSEDITPREFIXLEN, CVSEDITPREFIX, CVSEDITPREFIX); if (dir != NULL && *dir) (void) fprintf (fp, "%sCommitting in %s\n%s\n", CVSEDITPREFIX, dir, CVSEDITPREFIX); if (changes != NULL) setup_tmpfile (fp, CVSEDITPREFIX, changes); (void) fprintf (fp, "%s----------------------------------------------------------------------\n", CVSEDITPREFIX); /* finish off the temp file */ if (fclose (fp) == EOF) error (1, errno, "%s", fname); if (stat (fname, &pre_stbuf) == -1) pre_stbuf.st_mtime = 0; /* run the editor */ run_setup (Editor); run_add_arg (fname); if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL | RUN_SIGIGNORE | RUN_UNSETXID)) != 0) error (0, retcode == -1 ? errno : 0, "warning: editor session failed"); /* put the entire message back into the *messagep variable */ fp = xfopen (fname, "r"); if (*messagep) free (*messagep); if (stat (fname, &post_stbuf) != 0) error (1, errno, "cannot find size of temp file %s", fname); if (post_stbuf.st_size == 0) *messagep = NULL; else { /* On NT, we might read less than st_size bytes, but we won't read more. So this works. */ *messagep = (char *) xmalloc (post_stbuf.st_size + 1); (*messagep)[0] = '\0'; } line = NULL; line_chars_allocated = 0; if (*messagep) { size_t message_len = post_stbuf.st_size + 1; size_t offset = 0; while (1) { line_length = getline (&line, &line_chars_allocated, fp); if (line_length == -1) { if (ferror (fp)) error (0, errno, "warning: cannot read %s", fname); break; } if (strncmp (line, CVSEDITPREFIX, CVSEDITPREFIXLEN) == 0) continue; if (offset + line_length >= message_len) expand_string (messagep, &message_len, offset + line_length + 1); (void) strcpy (*messagep + offset, line); offset += line_length; } } if (fclose (fp) < 0) error (0, errno, "warning: cannot close %s", fname); /* canonicalize emply messages */ if (*messagep != NULL && (**messagep == '\0' || strcmp (*messagep, "\n") == 0)) { free (*messagep); *messagep = NULL; } if (pre_stbuf.st_mtime == post_stbuf.st_mtime || *messagep == NULL) { for (;;) { (void) printf ("\nLog message unchanged or not specified\n"); (void) printf ("a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs\n"); (void) printf ("Action: (abort) "); (void) fflush (stdout); line_length = getline (&line, &line_chars_allocated, stdin); if (line_length < 0) { error (0, errno, "cannot read from stdin"); if (unlink_file (fname) < 0) error (0, errno, "warning: cannot remove temp file %s", fname); error (1, 0, "aborting"); } else if (line_length == 0 || *line == '\n' || *line == 'a' || *line == 'A') { if (unlink_file (fname) < 0) error (0, errno, "warning: cannot remove temp file %s", fname); error (1, 0, "aborted by user"); } if (*line == 'c' || *line == 'C') break; if (*line == 'e' || *line == 'E') goto again; if (*line == '!') { reuse_log_message = 1; break; } (void) printf ("Unknown input\n"); } } if (line) free (line); if (unlink_file (fname) < 0) error (0, errno, "warning: cannot remove temp file %s", fname); free (fname); }
int DEFAULT_CC main(int argc, char **argv) { tbus waiters[4]; int pid = 0; char text[256]; char *home_text; char *display_text; char log_file[256]; enum logReturns error; struct log_config logconfig; g_init("xrdp-chansrv"); /* os_calls */ home_text = g_getenv("HOME"); if (home_text == 0) { g_writeln("error reading HOME environment variable"); g_deinit(); return 1; } read_ini(); pid = g_getpid(); /* starting logging subsystem */ g_memset(&logconfig, 0, sizeof(struct log_config)); logconfig.program_name = "XRDP-Chansrv"; g_snprintf(log_file, 255, "%s/xrdp-chansrv.log", home_text); g_writeln("chansrv::main: using log file [%s]", log_file); if (g_file_exist(log_file)) { g_file_delete(log_file); } logconfig.log_file = log_file; logconfig.fd = -1; logconfig.log_level = LOG_LEVEL_ERROR; logconfig.enable_syslog = 0; logconfig.syslog_level = 0; error = log_start_from_param(&logconfig); if (error != LOG_STARTUP_OK) { switch (error) { case LOG_ERROR_MALLOC: g_writeln("error on malloc. cannot start logging. quitting."); break; case LOG_ERROR_FILE_OPEN: g_writeln("error opening log file [%s]. quitting.", getLogFile(text, 255)); break; default: g_writeln("log_start error"); break; } g_deinit(); return 1; } LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid)); /* set up signal handler */ g_signal_kill(term_signal_handler); /* SIGKILL */ g_signal_terminate(term_signal_handler); /* SIGTERM */ g_signal_user_interrupt(term_signal_handler); /* SIGINT */ g_signal_pipe(nil_signal_handler); /* SIGPIPE */ g_signal_child_stop(child_signal_handler); /* SIGCHLD */ display_text = g_getenv("DISPLAY"); LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text)); get_display_num_from_display(display_text); if (g_display_num == 0) { LOGM((LOG_LEVEL_ERROR, "main: error, display is zero")); g_deinit(); return 1; } LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num)); g_snprintf(text, 255, "xrdp_chansrv_%8.8x_main_term", pid); g_term_event = g_create_wait_obj(text); g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid); g_thread_done_event = g_create_wait_obj(text); g_snprintf(text, 255, "xrdp_chansrv_%8.8x_exec", pid); g_exec_event = g_create_wait_obj(text); g_exec_mutex = tc_mutex_create(); g_exec_sem = tc_sem_create(0); tc_thread_create(channel_thread_loop, 0); while (g_term_event > 0 && !g_is_wait_obj_set(g_term_event)) { waiters[0] = g_term_event; waiters[1] = g_exec_event; if (g_obj_wait(waiters, 2, 0, 0, 0) != 0) { LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); break; } if (g_is_wait_obj_set(g_term_event)) { break; } if (g_is_wait_obj_set(g_exec_event)) { g_reset_wait_obj(g_exec_event); run_exec(); } } while (g_thread_done_event > 0 && !g_is_wait_obj_set(g_thread_done_event)) { /* wait for thread to exit */ if (g_obj_wait(&g_thread_done_event, 1, 0, 0, 0) != 0) { LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); break; } } /* cleanup */ main_cleanup(); LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid)); g_deinit(); return 0; }
/* * Builds a temporary file using setup_tmpfile() and invokes the user's * editor on the file. The header garbage in the resultant file is then * stripped and the log message is stored in the "message" argument. * * If REPOSITORY is non-NULL, process rcsinfo for that repository; if it * is NULL, use the CVSADM_TEMPLATE file instead. */ void do_editor (const char *dir, char **messagep, const char *repository, List *changes) { static int reuse_log_message = 0; char *line; int line_length; size_t line_chars_allocated; char *fname; struct stat pre_stbuf, post_stbuf; int retcode = 0; if (noexec || reuse_log_message) return; /* Abort creation of temp file if no editor is defined */ if (strcmp (Editor, "") == 0) error(1, 0, "no editor defined, must use -e or -m"); /* Create a temporary file */ /* FIXME - It's possible we should be relying on cvs_temp_file to open * the file here - we get race conditions otherwise. */ fname = cvs_temp_name (); again: if ((fp = CVS_FOPEN (fname, "w+")) == NULL) error (1, 0, "cannot create temporary file %s", fname); if (*messagep) { fprintf (fp, "%s", *messagep); if ((*messagep)[0] == '\0' || (*messagep)[strlen (*messagep) - 1] != '\n') fprintf (fp, "\n"); } if (repository != NULL) { rcsinfo_param_t args; args.directory = Short_Repository(repository); args.message=NULL; /* tack templates on if necessary */ TRACE(3,"run rcsinfo trigger"); if(!run_trigger(&args,rcsinfo_proc) && args.message) { fprintf(fp,"%s",args.message); if (args.message[0] == '\0' || args.message[strlen(args.message) - 1] != '\n') fprintf (fp, "\n"); } } else { FILE *tfp; char buf[1024]; size_t n; size_t nwrite; /* Why "b"? */ tfp = CVS_FOPEN (CVSADM_TEMPLATE, "rb"); if (tfp == NULL) { if (!existence_error (errno)) error (1, errno, "cannot read %s", CVSADM_TEMPLATE); } else { while (!feof (tfp)) { char *p = buf; n = fread (buf, 1, sizeof buf, tfp); nwrite = n; while (nwrite > 0) { n = fwrite (p, 1, nwrite, fp); nwrite -= n; p += n; } if (ferror (tfp)) error (1, errno, "cannot read %s", CVSADM_TEMPLATE); } if (fclose (tfp) < 0) error (0, errno, "cannot close %s", CVSADM_TEMPLATE); } } fprintf (fp,"%s----------------------------------------------------------------------\n",CVSEDITPREFIX); #ifdef _WIN32 #if (CVSNT_SPECIAL_BUILD_FLAG != 0) if (strcasecmp(CVSNT_SPECIAL_BUILD,"Suite")!=0) #endif { fprintf (fp,"%s Committed on the Free edition of March Hare Software CVSNT Server\n",CVSEDITPREFIX); fprintf (fp,"%s Upgrade to CVS Suite for more features and support:\n",CVSEDITPREFIX); fprintf (fp,"%s http://march-hare.com/cvsnt/\n",CVSEDITPREFIX); fprintf (fp,"%s----------------------------------------------------------------------\n",CVSEDITPREFIX); } #endif fprintf (fp,"%sEnter Log. Lines beginning with `%.*s' are removed automatically\n%s\n", CVSEDITPREFIX, CVSEDITPREFIXLEN, CVSEDITPREFIX,CVSEDITPREFIX); if (dir != NULL && *dir) fprintf (fp, "%sCommitting in %s\n%s\n", CVSEDITPREFIX, dir, CVSEDITPREFIX); if (changes != NULL) setup_tmpfile (fp, CVSEDITPREFIX, changes); fprintf (fp,"%s----------------------------------------------------------------------\n", CVSEDITPREFIX); /* finish off the temp file */ if (fclose (fp) == EOF) error (1, errno, "%s", fname); if ( CVS_STAT (fname, &pre_stbuf) == -1) pre_stbuf.st_mtime = 0; /* run the editor */ run_setup (Editor); run_arg (fname); if ((retcode = run_exec (true)) != 0) error (0, retcode == -1 ? errno : 0, "warning: editor session failed"); /* put the entire message back into the *messagep variable */ fp = open_file (fname, "r"); if (*messagep) xfree (*messagep); if ( CVS_STAT (fname, &post_stbuf) != 0) error (1, errno, "cannot find size of temp file %s", fname); if (post_stbuf.st_size == 0) *messagep = NULL; else { /* On NT, we might read less than st_size bytes, but we won't read more. So this works. */ *messagep = (char *) xmalloc (post_stbuf.st_size + 1); *messagep[0] = '\0'; } line = NULL; line_chars_allocated = 0; if (*messagep) { size_t message_len = post_stbuf.st_size + 1; size_t offset = 0; while (1) { line_length = getline (&line, &line_chars_allocated, fp); if (line_length == -1) { if (ferror (fp)) error (0, errno, "warning: cannot read %s", fname); break; } if (strncmp (line, CVSEDITPREFIX, CVSEDITPREFIXLEN) == 0) continue; if (offset + line_length >= message_len) expand_string (messagep, &message_len, offset + line_length + 1); strcpy (*messagep + offset, line); offset += line_length; } } if (fclose (fp) < 0) error (0, errno, "warning: cannot close %s", fname); if (pre_stbuf.st_mtime == post_stbuf.st_mtime || *messagep == NULL || strcmp (*messagep, "\n") == 0) { for (;;) { printf ("\nLog message unchanged or not specified\n"); printf ("a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs\n"); printf ("Action: (continue) "); fflush (stderr); fflush (stdout); line_length = getline (&line, &line_chars_allocated, stdin); if (line_length < 0) { error (0, errno, "cannot read from stdin"); if (unlink_file (fname) < 0) error (0, errno, "warning: cannot remove temp file %s", fname); error (1, 0, "aborting"); } else if (line_length == 0 || *line == '\n' || *line == 'c' || *line == 'C') break; if (*line == 'a' || *line == 'A') { if (unlink_file (fname) < 0) error (0, errno, "warning: cannot remove temp file %s", fname); error (1, 0, "aborted by user"); } if (*line == 'e' || *line == 'E') goto again; if (*line == '!') { reuse_log_message = 1; break; } printf ("Unknown input\n"); } } if (line) xfree (line); if (unlink_file (fname) < 0) error (0, errno, "warning: cannot remove temp file %s", fname); xfree (fname); }