/* CVSNT Checkout trigger handler Copyright (C) 2005 Tony Hoyle and March-Hare Software Ltd 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 */ #ifdef _WIN32 #pragma warning(disable:4503) // Decorated name length warning #endif #include #include #include #ifdef _WIN32 #include #include #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_DIRECT_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #define MODULE checkout #include #include #include #include "../version.h" #define CVSROOT_SHADOW "CVSROOT/shadow" static bool g_verbose; #ifndef _WIN32 static bool g_cifslogin; #endif cvs::filename g_repos; cvs::string g_command; std::map module_list; std::map tag_list; #ifdef _WIN32 HMODULE g_hInst; BOOL CALLBACK DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { g_hInst = hModule; return TRUE; } #include "checkout_resource.h" int win32config(const struct plugin_interface *ui, void *wnd); #endif int initcheckout(const struct trigger_interface_t* cb, const char *command, const char *date, const char *hostname, const char *username, const char *virtual_repository, const char *physical_repository, const char *sessionid, const char *editor, int count_uservar, const char **uservar, const char **userval, const char *client_version, const char *character_set) { char value[256]; int val = 0; if(!CGlobalSettings::GetGlobalValue("cvsnt","Plugins","CheckoutTrigger",value,sizeof(value))) val = atoi(value); if(!val) { CServerIo::trace(3,"Checkout trigger not enabled."); return -1; } else { CServerIo::trace(3,"Checkout trigger is enabled."); } #ifndef _WIN32 g_cifslogin = false; if(!CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutLogin",value,sizeof(value))) g_cifslogin = atoi(value)?true:false; #endif g_verbose = false; if(!CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutVerbose",value,sizeof(value))) g_verbose = atoi(value)?true:false; g_repos = physical_repository; g_command = command; return 0; } int closecheckout(const struct trigger_interface_t* cb) { return 0; } int pretagcheckout(const struct trigger_interface_t* cb, const char *message, const char *directory, int name_list_count, const char **name_list, const char **version_list, char tag_type, const char *action, const char *tag) { module_list[directory]++; if(tag && tag[0]) tag_list[tag]++; else tag_list["HEAD"]++; return 0; } int verifymsgcheckout(const struct trigger_interface_t* cb, const char *directory, const char *filename) { return 0; } int loginfocheckout(const struct trigger_interface_t* cb, const char *message, const char *status, const char *directory, int change_list_count, change_info_t *change_list) { module_list[directory]++; for(int n=0; n::const_iterator i = module_list.begin(); i!=module_list.end(); ++i) { CServerIo::trace(3,"Regexp match: %s - %s",tok[0],i->first.c_str()); cvs::wildcard_filename mod(i->first.c_str()); if(mod.matches_regexp(tok[0])) // Wildcard match { CServerIo::trace(3,"Match found!"); found=true; match = i->first.c_str(); break; } } if(!found) continue; found=false; for(std::map::const_iterator i = tag_list.begin(); i!=tag_list.end(); ++i) { if(!strcmp(i->first.c_str(),tok[1])) { found=true; break; } } if(!found) continue; #ifndef _WIN32 if(g_cifslogin) { CRunFile rf1; char host[256],name[256]="cifslogin",user[256]="",password[256]=""; if(CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutLoginUser",user,sizeof(user))) { CServerIo::trace(3,"Checkout plugin: Login user name not set"); user[0]='\0'; } if(CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutLoginPassword",password,sizeof(password))) { CServerIo::trace(3,"Checkout plugin: Login password not set"); password[0]='\0'; } if(CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutLoginCommand",name,sizeof(name))) { CServerIo::trace(3,"Checkout plugin: Login command not set - assume \"cifslogin\""); strcpy(name,"cifslogin"); } if(CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutLoginServer",host,sizeof(host))) { CServerIo::trace(3,"Checkout plugin: Login server not set"); host[0]='\0'; } if (*host) { rf1.setOutput(outputProc,NULL); rf1.setError(errorProc,NULL); rf1.addArg(name); if (*password) { rf1.addArg("-P"); rf1.addArg(password); } rf1.addArg(host); if (*user) rf1.addArg(user); if(!rf1.run(NULL)) { CServerIo::error("Unable to run checkout login command"); return 0; } int ret; rf1.wait(ret); } } #endif CRunFile rf; char cvscmd[2048]="\0"; char cvsopt[2048]="\0"; char cvscmdopt[2048]="\0"; rf.setOutput(outputProc,NULL); rf.setError(errorProc,NULL); if(CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutCommand",cvscmd,sizeof(cvscmd))) { CServerIo::trace(3,"Checkout plugin: Command not set - usng default"); rf.addArg(CGlobalSettings::GetCvsCommand()); } else { CServerIo::trace(3,"Checkout plugin: Using specified command"); rf.addArg(cvscmd); } if(!CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutOption",cvsopt,sizeof(cvsopt))) { CServerIo::trace(3,"Checkout plugin: Options set - %s",cvsopt); rf.addArg(cvsopt); } rf.addArg("-d"); rf.addArg(g_repos.c_str()); rf.addArg("co"); if(!CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutCommandOption",cvscmdopt,sizeof(cvscmdopt))) { CServerIo::trace(3,"Checkout plugin: Command options set - %s",cvscmdopt); rf.addArg(cvscmdopt); } rf.addArg("-d"); rf.addArg(tok[2]); rf.addArg("-r"); rf.addArg(tok[1]); rf.addArg(match.c_str()); if(!rf.run(NULL)) { CServerIo::error("Unable to run cvs checkout"); return 0; } int ret; rf.wait(ret); } return 0; } int premodulecheckout(const struct trigger_interface_t* cb, const char *module) { module_list[module]++; return 0; } int postmodulecheckout(const struct trigger_interface_t* cb, const char *module) { module_list[module]++; return 0; } int get_templatecheckout(const struct trigger_interface_t *cb, const char *directory, const char **template_ptr) { return 0; } int parse_keywordcheckout(const struct trigger_interface_t *cb, const char *keyword,const char *directory,const char *file,const char *branch,const char *author,const char *printable_date,const char *rcs_date,const char *locker,const char *state,const char *version,const char *name,const char *bugid, const char *commitid, const property_info *props, size_t numprops, const char **value) { return 0; } int prercsdiffcheckout(const struct trigger_interface_t *cb, const char *file, const char *directory, const char *oldfile, const char *newfile, const char *type, const char *options, const char *oldversion, const char *newversion, unsigned long added, unsigned long removed) { return 0; } int rcsdiffcheckout(const struct trigger_interface_t *cb, const char *file, const char *directory, const char *oldfile, const char *newfile, const char *diff, size_t difflen, const char *type, const char *options, const char *oldversion, const char *newversion, unsigned long added, unsigned long removed) { return 0; } static int init(const struct plugin_interface *plugin); static int destroy(const struct plugin_interface *plugin); static void *get_interface(const struct plugin_interface *plugin, unsigned interface_type, void *param); static trigger_interface callbacks = { { PLUGIN_INTERFACE_VERSION, "Automatic checkout extension",CVSNT_PRODUCTVERSION_STRING,"CheckoutTrigger", init, destroy, get_interface, #ifdef _WIN32 win32config #else NULL #endif }, initcheckout, closecheckout, pretagcheckout, verifymsgcheckout, loginfocheckout, historycheckout, notifycheckout, precommitcheckout, postcommitcheckout, precommandcheckout, postcommandcheckout, premodulecheckout, postmodulecheckout, get_templatecheckout, parse_keywordcheckout, prercsdiffcheckout, rcsdiffcheckout }; static int init(const struct plugin_interface *plugin) { return 0; } static int destroy(const struct plugin_interface *plugin) { return 0; } static void *get_interface(const struct plugin_interface *plugin, unsigned interface_type, void *param) { if(interface_type!=pitTrigger) return NULL; return (void*)&callbacks; } plugin_interface *get_plugin_interface() { return &callbacks.plugin; } #ifdef _WIN32 BOOL CALLBACK ConfigDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { char value[MAX_PATH]; int nSel; switch(uMsg) { case WM_INITDIALOG: nSel = 0; if(!CGlobalSettings::GetGlobalValue("cvsnt","Plugins","CheckoutTrigger",value,sizeof(value))) nSel = atoi(value); if(!nSel) { EnableWindow(GetDlgItem(hWnd,IDC_CHECK2),FALSE); EnableWindow(GetDlgItem(hWnd,IDC_CHECKOUTDEF),FALSE); EnableWindow(GetDlgItem(hWnd,IDC_CHECKOUTMOD),FALSE); EnableWindow(GetDlgItem(hWnd,IDC_COMMANDNAME),FALSE); EnableWindow(GetDlgItem(hWnd,IDC_COMMANDOPT),FALSE); EnableWindow(GetDlgItem(hWnd,IDC_VERBOPT),FALSE); } else SendDlgItemMessage(hWnd,IDC_CHECK1,BM_SETCHECK,1,NULL); nSel = 0; if(!CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutVerbose",value,sizeof(value))) nSel = atoi(value); SendDlgItemMessage(hWnd,IDC_CHECK2,BM_SETCHECK,nSel?1:0,NULL); if(!CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutOption",value,sizeof(value))) SetDlgItemText(hWnd,IDC_COMMANDOPT,value); if(!CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutCommandOption",value,sizeof(value))) SetDlgItemText(hWnd,IDC_VERBOPT,value); if(!CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutCommand",value,sizeof(value))) SetDlgItemText(hWnd,IDC_COMMANDNAME,value); else value[0]='\0'; if(*value) { CheckRadioButton(hWnd,IDC_CHECKOUTDEF,IDC_CHECKOUTMOD,IDC_CHECKOUTMOD); EnableWindow(GetDlgItem(hWnd,IDC_COMMANDOPT),TRUE); EnableWindow(GetDlgItem(hWnd,IDC_VERBOPT),TRUE); EnableWindow(GetDlgItem(hWnd,IDC_COMMANDNAME),TRUE); } else { CheckRadioButton(hWnd,IDC_CHECKOUTDEF,IDC_CHECKOUTMOD,IDC_CHECKOUTDEF); EnableWindow(GetDlgItem(hWnd,IDC_COMMANDOPT),FALSE); EnableWindow(GetDlgItem(hWnd,IDC_VERBOPT),FALSE); EnableWindow(GetDlgItem(hWnd,IDC_COMMANDNAME),FALSE); } return FALSE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_CHECK1: nSel=SendDlgItemMessage(hWnd,IDC_CHECK1,BM_GETCHECK,NULL,NULL); EnableWindow(GetDlgItem(hWnd,IDC_CHECK2),nSel?TRUE:FALSE); EnableWindow(GetDlgItem(hWnd,IDC_CHECKOUTDEF),nSel?TRUE:FALSE); EnableWindow(GetDlgItem(hWnd,IDC_CHECKOUTMOD),nSel?TRUE:FALSE); if (!nSel) { EnableWindow(GetDlgItem(hWnd,IDC_COMMANDNAME),FALSE); EnableWindow(GetDlgItem(hWnd,IDC_COMMANDOPT),FALSE); EnableWindow(GetDlgItem(hWnd,IDC_VERBOPT),FALSE); } return TRUE; case IDC_CHECKOUTDEF: EnableWindow(GetDlgItem(hWnd,IDC_COMMANDNAME),FALSE); EnableWindow(GetDlgItem(hWnd,IDC_COMMANDOPT),FALSE); EnableWindow(GetDlgItem(hWnd,IDC_VERBOPT),FALSE); value[0]='\0'; SetDlgItemText(hWnd,IDC_COMMANDNAME,value); SetDlgItemText(hWnd,IDC_COMMANDOPT,value); SetDlgItemText(hWnd,IDC_VERBOPT,value); return TRUE; case IDC_CHECKOUTMOD: if(!CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutCommand",value,sizeof(value))) SetDlgItemText(hWnd,IDC_COMMANDNAME,value); if(!CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutOption",value,sizeof(value))) SetDlgItemText(hWnd,IDC_COMMANDOPT,value); if(!CGlobalSettings::GetGlobalValue("cvsnt","PServer","CheckoutCommandOption",value,sizeof(value))) SetDlgItemText(hWnd,IDC_VERBOPT,value); EnableWindow(GetDlgItem(hWnd,IDC_COMMANDNAME),TRUE); EnableWindow(GetDlgItem(hWnd,IDC_COMMANDOPT),TRUE); EnableWindow(GetDlgItem(hWnd,IDC_VERBOPT),TRUE); return TRUE; case IDOK: nSel=SendDlgItemMessage(hWnd,IDC_CHECK1,BM_GETCHECK,NULL,NULL); CGlobalSettings::SetGlobalValue("cvsnt","Plugins","CheckoutTrigger",nSel); nSel=SendDlgItemMessage(hWnd,IDC_CHECK2,BM_GETCHECK,NULL,NULL); CGlobalSettings::SetGlobalValue("cvsnt","PServer","CheckoutVerbose",nSel); GetDlgItemText(hWnd,IDC_COMMANDNAME,value,sizeof(value)); CGlobalSettings::SetGlobalValue("cvsnt","PServer","CheckoutCommand",value); GetDlgItemText(hWnd,IDC_COMMANDOPT,value,sizeof(value)); CGlobalSettings::SetGlobalValue("cvsnt","PServer","CheckoutOption",value); GetDlgItemText(hWnd,IDC_VERBOPT,value,sizeof(value)); CGlobalSettings::SetGlobalValue("cvsnt","PServer","CheckoutCommandOption",value); case IDCANCEL: EndDialog(hWnd,LOWORD(wParam)); return TRUE; } break; } return FALSE; } int win32config(const struct plugin_interface *ui, void *wnd) { HWND hWnd = (HWND)wnd; int ret = DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, ConfigDlgProc); return ret==IDOK?0:-1; } #endif