/* ** The cvsgui protocol used by WinCvs ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public ** License as published by the Free Software Foundation; either ** version 2.1 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Lesser General Public License for more details. ** ** You should have received a copy of the GNU Lesser General Public ** License along with this library; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Author : Alexandre Parenteau --- November 1999 */ /* * cvsgui.c --- glue code for communicating with cvs over pipes */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #if defined(WIN32) && !defined(PATH_MAX) # ifdef _MAX_PATH # define PATH_MAX _MAX_PATH # else # define PATH_MAX 512 # endif #endif #include "cvsgui_process.h" #include "cvsgui_protocol.h" #undef main #undef getpass #undef getenv #undef exit #ifdef WIN32 extern char *getpass(const char *prompt); #endif pipe_t _cvsgui_readfd = 0; pipe_t _cvsgui_writefd = 0; static long outseek; static long errseek; static char outname[PATH_MAX] = {0}; static char errname[PATH_MAX] = {0}; static FILE *outlog; static FILE *errlog; char * cvsguiglue_getenv(const char *env) { char *res = 0L; if(_cvsgui_readfd == 0) return getenv(env); cvsguiglue_flushconsole(0); if(env && gp_getenv_write (_cvsgui_writefd, env)) { res = gp_getenv_read(_cvsgui_readfd);; } #if qCvsDebug fprintf(stderr, "%s=%s\n", env, res); #endif return res; } char * cvsguiglue_getpass(const char *prompt) { cvsguiglue_flushconsole(0); if(_cvsgui_readfd == 0) return getpass(prompt); return cvsguiglue_getenv("CVS_GETPASS"); } void cvsguiglue_exit(int code) { cvsguiglue_flushconsole(1); if(_cvsgui_writefd != 0) gp_quit_write (_cvsgui_writefd, code); exit(code); } static void reopen_consoles(void) { #if !defined(WIN32) && !defined(__GNUC__) strcpy(outname, tempnam(0L, 0L)); strcpy(errname, tempnam(0L, 0L)); strcat(outname, ".out"); strcat(errname, ".err"); outlog = freopen(outname, "w+", stdout); if(outlog == 0L) { fprintf(stderr, "Unable to reopen stdout !\n"); exit(1); } errlog = freopen(errname, "w+", stderr); if(errlog == 0L) { fprintf(stderr, "Unable to reopen stderr !\n"); exit(1); } outseek = 0; errseek = 0; #endif } static void close_consoles(void) { #if !defined(WIN32) && !defined(__GNUC__) if(outlog != 0L) fclose(outlog); if(errlog != 0L) fclose(errlog); if(outname[0]) unlink(outname); if(errname[0]) unlink(errname); outlog = 0L; errlog = 0L; outname[0] = '\0'; errname[0] = '\0'; #endif } static void myflush(FILE *log, long *oldpos) { long newpos, pos; # define BUF_SIZE 8000 char buf[BUF_SIZE]; size_t len; pos = fseek(log, *oldpos, SEEK_SET); if(pos != 0) goto fail; while(!feof(log) && !ferror(log)) { len = fread(buf, sizeof(char), BUF_SIZE, log); if(len > 0) { if(log == outlog) gp_console_write (_cvsgui_writefd, buf, len, 0); if(log == errlog) gp_console_write (_cvsgui_writefd, buf, len, 1); } } if(ferror(log)) goto fail; newpos = ftell(log); if(newpos < 0) goto fail; *oldpos = newpos; return; fail: fprintf(stderr, "Unable to redirect stdout/stderr !\n"); } void cvsguiglue_flushconsole(int closeit) { fflush(stdout); fflush(stderr); #if !defined(WIN32) && !defined(__GNUC__) if(outlog != 0L) myflush(outlog, &outseek); if(errlog != 0L) myflush(errlog, &errseek); if(closeit) close_consoles(); #endif } int main(int argc, char *argv[]) { int res; char **tmparg = 0L; if(argc >= 4 && strcmp(argv[1], "-cvsgui") == 0) { int i; _cvsgui_readfd = (pipe_t)atoi (argv[2]); _cvsgui_writefd = (pipe_t)atoi (argv[3]); tmparg = (char **)malloc((argc - 2) * sizeof(char *)); if(tmparg == 0L) goto ignore; tmparg[0] = argv[0]; for(i = 4; i < argc; i++) { tmparg[i - 3] = argv[i]; } tmparg[argc - 3] = 0L; argc -= 3; cvs_process_init(); reopen_consoles(); } ignore: res = cvsguiglue_main(argc, tmparg != 0L ? tmparg : argv); if(tmparg != 0L) { cvsguiglue_flushconsole(1); if(_cvsgui_writefd != 0) gp_quit_write (_cvsgui_writefd, res); free(tmparg); } return res; }