Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com From: "Ralf Habacker" To: "Cygwin" Subject: Problems implementing service installer in cron-2.9.3 Date: Tue, 8 May 2001 08:33:21 +0200 Message-ID: <001101c0d788$c6c0ebb0$6e032bb7@BRAMSCHE> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0012_01C0D799.8A49BBB0" X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 Importance: Normal X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 ------=_NextPart_000_0012_01C0D799.8A49BBB0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Hi, I like to integrate a service installer in cron and have adapted the service code from cygipc. I can compile this stuff, install/remove the service, but starting don't work. Has anyone an idea, what I have done wrong ? The relating code is appended. Regards Ralf Habacker EMail: Ralf AT habacker DOT de Ralf DOT Habacker AT saght DOT tessag DOT com ------=_NextPart_000_0012_01C0D799.8A49BBB0 Content-Type: application/octet-stream; name="service.cc" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="service.cc" /* $Id: ip-daemon.c,v 1.14 2001/02/16 16:15:07 cwilson Exp $ */=0A= =0A= /*=0A= * service installer=0A= *=0A= * Copyright (C) 1997 Philippe CHAPUY=0A= * Copyright (C) 1998 Ludovic LANGE=0A= *=0A= * This program is free software; you can redistribute it and/or modify=0A= * it under the terms of the GNU General Public License as published by=0A= * the Free Software Foundation; either version 2 of the License, or=0A= * (at your option) any later version.=0A= *=0A= * This program is distributed in the hope that it will be useful,=0A= * but WITHOUT ANY WARRANTY; without even the implied warranty of=0A= * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the=0A= * GNU General Public License for more details.=0A= *=0A= * You should have received a copy of the GNU General Public License=0A= * along with this program; if not, write to the Free Software=0A= * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=0A= */=0A= =0A= /*=0A= * HISTORY:=0A= * --------=0A= *=0A= * 13/05/1998 : Version 1.00 released=0A= * First public release=0A= * adress any comments to llange AT capgemini DOT fr=0A= *=0A= */=0A= =0A= /*=0A= * About fprintf, syslog, and log_message:=0A= * if a message needs to be sent to the user, then use these=0A= * functions under the following circumstances:=0A= * - fprintf: stuff that is immediately user-interactive=0A= * e.g. you don't want to see "help instructions" =0A= * in the syslog.=0A= * - syslog: when the block of code is only reachable=0A= * when running as a service --- but, for simplicity,=0A= * we just use log_message anyway.=0A= * - log_message: when the block of code could be reached=0A= * when running as a service OR standalone=0A= */=0A= =0A= /************************************************************************= /=0A= /* */=0A= /************************************************************************= /=0A= =0A= //#define EXTERN=0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include "service.h"=0A= =0A= int work_main(void);=0A= =0A= char * getVersion(char * buf, int len);=0A= static void get_null_sa (SECURITY_ATTRIBUTES *sap);=0A= int get_reg_entries(void);=0A= int log_message(FILE *stream, int severity, const char *fmt, ...);=0A= =0A= char verbose=3D1;=0A= int service=3D0;=0A= char tight_security=3D0;=0A= char debug=3D0;=0A= =0A= #define is_winnt (GetVersion() < 0x80000000)=0A= =0A= #define CROND_SERVICE_NAME "cron-daemon1"=0A= #define CROND_SERVICE_DISPLAY "Cron Daemon"=0A= #define CROND_PARAM_KEY "SYSTEM\\CurrentControlSet\\Services\\" \=0A= CROND_SERVICE_NAME \=0A= "\\Parameters"=0A= #define CROND_PARAM_SECURITY "TightSecurity"=0A= #define CROND_PARAM_DEBUG "Debug"=0A= =0A= int server_pid =3D 0;=0A= SERVICE_STATUS_HANDLE ssh;=0A= SERVICE_STATUS ss;=0A= HANDLE hStopEvent =3D NULL;=0A= =0A= =0A= int install_reg_entries(const char *myname, int verbose)=0A= {=0A= HKEY srv_key =3D NULL;=0A= DWORD disp;=0A= DWORD temp;=0A= char *err_func;=0A= =0A= if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, CROND_PARAM_KEY, 0, "",=0A= REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,=0A= NULL, &srv_key, &disp)=0A= !=3D ERROR_SUCCESS)=0A= {=0A= err_func =3D "RegCreateKeyEx";=0A= goto error;=0A= }=0A= temp =3D tight_security;=0A= if (RegSetValueEx(srv_key, CROND_PARAM_SECURITY, 0, REG_DWORD,=0A= (CONST BYTE *) &temp, sizeof(DWORD))=0A= !=3D ERROR_SUCCESS)=0A= {=0A= err_func =3D "RegSetValueEx(TightSecurity=3D1)";=0A= goto error;=0A= }=0A= temp =3D debug;=0A= if (RegSetValueEx(srv_key, CROND_PARAM_DEBUG, 0, REG_DWORD,=0A= (CONST BYTE *) &temp, sizeof(DWORD))=0A= !=3D ERROR_SUCCESS)=0A= {=0A= err_func =3D "RegSetValueEx(Debug=3D1)";=0A= goto error;=0A= }=0A= RegFlushKey(srv_key);=0A= RegCloseKey(srv_key);=0A= return 0;=0A= error:=0A= if (srv_key)=0A= RegCloseKey(srv_key);=0A= if (verbose)=0A= log_message(stderr, LOG_ERR, "%s: %ld =3D %s()\n",=0A= myname, GetLastError(), err_func);=0A= log_message(stderr, LOG_ERR, =0A= "%s: installing registry entries for `cron-daemon' failed\n",=0A= myname);=0A= return 1;=0A= }=0A= =0A= int get_reg_entries(void)=0A= {=0A= HKEY srv_key =3D NULL;=0A= DWORD type, size;=0A= DWORD tight_security_temp;=0A= DWORD debug_temp;=0A= =0A= if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, CROND_PARAM_KEY, 0,=0A= KEY_ALL_ACCESS, &srv_key)=0A= !=3D ERROR_SUCCESS)=0A= {=0A= log_message(stderr, LOG_WARNING, =0A= "couldn't get parameters from registry, using defaults\n"=0A= "error %ld in RegOpenKeyEx()", GetLastError());=0A= return 1;=0A= }=0A= if (RegQueryValueEx(srv_key, CROND_PARAM_DEBUG, 0, &type,=0A= (unsigned char *) &debug_temp, (size =3D = sizeof(DWORD), &size))=0A= !=3D ERROR_SUCCESS)=0A= log_message(stderr, LOG_WARNING, =0A= "couldn't get debug value from registry, "=0A= "using default value %d", debug);=0A= else {=0A= debug =3D (char) debug_temp;=0A= log_message(stderr, LOG_DEBUG, "debug value: %d", debug);=0A= }=0A= if (RegQueryValueEx(srv_key, CROND_PARAM_SECURITY, 0, &type,=0A= (unsigned char *) &tight_security_temp, (size =3D sizeof(DWORD), = &size))=0A= !=3D ERROR_SUCCESS)=0A= log_message(stderr, LOG_WARNING, =0A= "couldn't get tight_security boolean from registry, "=0A= "using default value %d", tight_security);=0A= else {=0A= tight_security =3D (char) tight_security_temp;=0A= log_message(stderr, LOG_DEBUG, "tight_security value: %d", = tight_security);=0A= }=0A= RegCloseKey(srv_key);=0A= return 0;=0A= }=0A= =0A= VOID WINAPI=0A= service_handler(DWORD ctrl)=0A= {=0A= exception_list except_list;=0A= cygwin_internal (CW_INIT_EXCEPTIONS, &except_list);=0A= switch (ctrl) {=0A= case SERVICE_CONTROL_STOP:=0A= ss.dwCheckPoint =3D 1;=0A= ss.dwWaitHint =3D 3000L; // wait up to 3 seconds...=0A= ss.dwCurrentState =3D SERVICE_STOP_PENDING;=0A= =0A= if (hStopEvent) {=0A= log_message(stderr, LOG_INFO, "sending hStopEvent");=0A= SetEvent(hStopEvent);=0A= }=0A= else=0A= log_message(stderr, LOG_INFO, "no hStopEvent to send");=0A= =0A= break;=0A= default:=0A= // ignore=0A= break;=0A= }=0A= SetServiceStatus(ssh, &ss);=0A= }=0A= =0A= void WINAPI=0A= service_main(DWORD argc, LPSTR *argv)=0A= {=0A= exception_list except_list;=0A= cygwin_internal (CW_INIT_EXCEPTIONS, &except_list);=0A= // Initialized Cygwin exception handling for thread not=0A= // created by Cygwin.=0A= =0A= if (! (ssh =3D RegisterServiceCtrlHandlerA(CROND_SERVICE_NAME,=0A= service_handler))) {=0A= log_message(stderr, LOG_ERR,=0A= "error in service_main: %d =3D = RegSrvCtrlHandler()",=0A= GetLastError());=0A= log_message(stderr, LOG_ERR, "starting 'cron-daemon' as = a service failed");=0A= return;=0A= }=0A= ss.dwServiceType =3D SERVICE_WIN32_SHARE_PROCESS;=0A= ss.dwCurrentState =3D SERVICE_START_PENDING;=0A= ss.dwControlsAccepted =3D SERVICE_ACCEPT_STOP;=0A= ss.dwWin32ExitCode =3D NO_ERROR;=0A= ss.dwCheckPoint =3D 1;=0A= ss.dwWaitHint =3D 3000L;=0A= SetServiceStatus(ssh, &ss);=0A= =0A= get_reg_entries();=0A= log_message(stderr, LOG_DEBUG, "service: %d, debug %d, = tight_security %d",=0A= service, debug, tight_security);=0A= work_main();=0A= =0A= log_message(stderr, LOG_INFO, "'cron-daemon' service stopped");=0A= ss.dwCheckPoint =3D 0;=0A= ss.dwCurrentState =3D SERVICE_STOPPED;=0A= SetServiceStatus(ssh, &ss);=0A= }=0A= =0A= int=0A= install_as_service(const char *myname, int verbose)=0A= {=0A= char mypath[MAX_PATH+5];=0A= char *err_func;=0A= SC_HANDLE sm =3D (SC_HANDLE) 0;=0A= SC_HANDLE sh =3D (SC_HANDLE) 0;=0A= SC_LOCK sl =3D (SC_LOCK) 0;=0A= =0A= // get own full path name=0A= if (! GetModuleFileName(NULL, mypath, MAX_PATH))=0A= {=0A= err_func =3D "GetModuleFileName";=0A= goto error;=0A= }=0A= // we can't read parameters from registry unless we=0A= // already know we are a service. So, appname must include=0A= // --service option:=0A= strcat(mypath, " \"--service\"");=0A= // open service manager database=0A= if (! (sm =3D OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)))=0A= {=0A= err_func =3D "OpenSCManager";=0A= goto error;=0A= }=0A= // lock service database=0A= if (! (sl =3D LockServiceDatabase(sm)))=0A= {=0A= err_func =3D "LockServiceDatabase";=0A= goto error;=0A= }=0A= // open service, go ahead if service doesn't exists=0A= if (! (sh =3D OpenService(sm, CROND_SERVICE_NAME, SERVICE_ALL_ACCESS)) = &&=0A= GetLastError() !=3D ERROR_SERVICE_DOES_NOT_EXIST)=0A= {=0A= err_func =3D "OpenService";=0A= goto error;=0A= }=0A= // service already exists=0A= if (sh)=0A= {=0A= if (verbose)=0A= log_message(stderr, LOG_WARNING, "%s: service already = installed", myname);=0A= }=0A= // no, create service=0A= else if (! (sh =3D CreateService(sm,=0A= CROND_SERVICE_NAME,=0A= CROND_SERVICE_DISPLAY,=0A= STANDARD_RIGHTS_REQUIRED |=0A= SERVICE_INTERROGATE |=0A= SERVICE_QUERY_STATUS |=0A= SERVICE_START |=0A= SERVICE_STOP,=0A= SERVICE_WIN32_OWN_PROCESS /*|=0A= SERVICE_INTERACTIVE_PROCESS*/,=0A= SERVICE_AUTO_START,=0A= SERVICE_ERROR_NORMAL,=0A= mypath,=0A= NULL,=0A= NULL,=0A= NULL,=0A= NULL,=0A= NULL=0A= )))=0A= {=0A= err_func =3D "CreateService";=0A= goto error;=0A= }=0A= =0A= // if CloseServiceHandle returns with error, it's not sure=0A= // whether anything works...=0A= if (! CloseServiceHandle(sh))=0A= {=0A= err_func =3D "CloseServiceHandle";=0A= goto error;=0A= }=0A= return 0;=0A= error:=0A= if (verbose)=0A= log_message(stderr, LOG_ERR, "%s: %lu =3D %s()",=0A= myname, GetLastError(), err_func);=0A= log_message(stderr, LOG_ERR, "%s: installing service `cron-daemon' = failed", myname);=0A= if (sh)=0A= CloseServiceHandle(sh);=0A= if (sl && ! UnlockServiceDatabase(sl))=0A= log_message(stderr, LOG_WARNING,=0A= "%s: CAUTION: UnlockServiceDatabase() failed "=0A= "with error %lu", myname, GetLastError());=0A= return 1;=0A= }=0A= =0A= int=0A= remove_as_service(const char *myname, int verbose)=0A= {=0A= char *err_func;=0A= SC_HANDLE sm =3D (SC_HANDLE) 0;=0A= SC_HANDLE sh =3D (SC_HANDLE) 0;=0A= SC_LOCK sl =3D (SC_LOCK) 0;=0A= SERVICE_STATUS ss;=0A= int err;=0A= =0A= // open service manager database=0A= if (! (sm =3D OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)))=0A= {=0A= err_func =3D "OpenSCManager";=0A= goto error;=0A= }=0A= // lock service database=0A= if (! (sl =3D LockServiceDatabase(sm)))=0A= {=0A= err_func =3D "LockServiceDatabase";=0A= goto error;=0A= }=0A= // check whether service exists=0A= if (! (sh =3D OpenService(sm, CROND_SERVICE_NAME, SERVICE_ALL_ACCESS)))=0A= {=0A= if (GetLastError() =3D=3D ERROR_SERVICE_DOES_NOT_EXIST)=0A= {=0A= if (verbose)=0A= log_message(stderr, LOG_ERR, "%s: service isn't installed", = myname);=0A= if (! UnlockServiceDatabase(sl))=0A= log_message(stderr, LOG_WARNING,=0A= "%s: CAUTION: UnlockServiceDatabase() failed "=0A= "with error %lu", myname, GetLastError());=0A= return 0;=0A= }=0A= err_func =3D "OpenService";=0A= goto error;=0A= }=0A= // try stopping service=0A= // if NOT_ACTIVE or CANNOT_ACCEPT_CTRL go ahead, else exit=0A= if (! ControlService(sh, SERVICE_CONTROL_STOP, &ss) &&=0A= (err =3D GetLastError()) !=3D ERROR_SERVICE_NOT_ACTIVE &&=0A= err !=3D ERROR_SERVICE_CANNOT_ACCEPT_CTRL)=0A= {=0A= err_func =3D "ControlService";=0A= goto error;=0A= }=0A= // wait, 'til service is stopped=0A= do=0A= {=0A= sleep(1);=0A= if (! QueryServiceStatus(sh, &ss))=0A= {=0A= err_func =3D "QueryServiceStatus";=0A= goto error;=0A= }=0A= }=0A= while (ss.dwCurrentState !=3D SERVICE_STOPPED);=0A= // remove service=0A= if (! DeleteService(sh))=0A= {=0A= err_func =3D "DeleteService";=0A= goto error;=0A= }=0A= // if CloseServiceHandle returns with error, it's not sure=0A= // whether anything works...=0A= if (! CloseServiceHandle(sh))=0A= {=0A= sh =3D (SC_HANDLE) 0;=0A= err_func =3D "CloseServiceHandle";=0A= goto error;=0A= }=0A= sh =3D (SC_HANDLE) 0;=0A= // Datenbank-Lock aufheben=0A= if (sl && ! UnlockServiceDatabase(sl))=0A= {=0A= log_message(stderr, LOG_WARNING,=0A= "%s: CAUTION: UnlockServiceDatabase() failed "=0A= "with error %lu", myname, GetLastError());=0A= }=0A= return 0;=0A= error:=0A= if (verbose)=0A= log_message(stderr, LOG_ERR, "%s: %lu =3D %s()",=0A= myname, GetLastError(), err_func);=0A= log_message(stderr, LOG_ERR, "%s: removing `cron-daemon' as service = failed", myname);=0A= if (sh)=0A= CloseServiceHandle(sh);=0A= if (sl && ! UnlockServiceDatabase(sl))=0A= fprintf(stderr,=0A= "%s: CAUTION: UnlockServiceDatabase() failed "=0A= "with error %lu", myname, GetLastError());=0A= return 1;=0A= }=0A= =0A= //=0A= // start service =0A= //=0A= //=0A= =0A= int start_service(void)=0A= {=0A= SERVICE_TABLE_ENTRYA ste[2];=0A= ste[0].lpServiceName =3D CROND_SERVICE_NAME;=0A= ste[0].lpServiceProc =3D service_main;=0A= ste[1].lpServiceName =3D NULL;=0A= ste[1].lpServiceProc =3D NULL;=0A= StartServiceCtrlDispatcherA(ste);=0A= return 0; =0A= }=0A= =0A= =0A= =0A= char * getVersion(char * buf, int len)=0A= {=0A= unsigned short LVersionMajor=3D1;=0A= unsigned short LVersionMinor=3D0;=0A= =0A= // LVersionMajor=3D(unsigned short)VERSION_NUM;=0A= // LVersionMinor=3D(unsigned short)( (VERSION_NUM-LVersionMajor)*100 );=0A= snprintf(buf, len, "%d.%02d", LVersionMajor, LVersionMinor);=0A= return buf;=0A= }=0A= =0A= static void get_null_sa (LPSECURITY_ATTRIBUTES sap)=0A= {=0A= static SECURITY_DESCRIPTOR *null_sdp =3D 0;=0A= static SECURITY_DESCRIPTOR sd;=0A= =0A= if (!sap)=0A= return;=0A= if (!null_sdp)=0A= {=0A= InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);=0A= SetSecurityDescriptorDacl (&sd, TRUE, 0, FALSE);=0A= null_sdp =3D &sd;=0A= }=0A= sap->nLength =3D sizeof *sap;=0A= sap->lpSecurityDescriptor =3D null_sdp;=0A= sap->bInheritHandle =3D TRUE;=0A= }=0A= =0A= int log_message(FILE *stream, int severity, const char *fmt, ...)=0A= {=0A= char buf[2000];=0A= va_list ap;=0A= int count;=0A= =0A= if( (debug) || (severity < LOG_DEBUG))=0A= {=0A= count =3D snprintf (buf, 2000, "(cron-daemon) ");=0A= va_start (ap, fmt);=0A= count +=3D vsnprintf (buf + count, 2000 - count, fmt, ap);=0A= va_end (ap);=0A= if(service)=0A= syslog(severity, buf);=0A= else=0A= {=0A= snprintf(buf + count, 2000 - count, "\n");=0A= fprintf(stream, buf);=0A= }=0A= }=0A= return 0;=0A= }=0A= =0A= ------=_NextPart_000_0012_01C0D799.8A49BBB0 Content-Type: application/octet-stream; name="service.h" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="service.h" #ifndef __SERVICE_H #define __SERVICE_H int install_reg_entries(const char *myname, int verbose); int install_as_service(const char *myname, int verbose); int remove_as_service(const char *myname, int verbose); int start_service(void); char * getVersion(char * buf, int len); // show active service state extern int service; #endif ------=_NextPart_000_0012_01C0D799.8A49BBB0 Content-Type: application/octet-stream; name="Makefile" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="Makefile" # Makefile - Makefile for cron=0A= # Copyright (C) 1998 Corinna Vinschen =0A= #=0A= # This program is free software; you can redistribute it and/or modify=0A= # it under the terms of the GNU General Public License as published by=0A= # the Free Software Foundation; either version 2, or (at your option)=0A= # any later version.=0A= #=0A= # This program is distributed in the hope that it will be useful,=0A= # but WITHOUT ANY WARRANTY; without even the implied warranty of=0A= # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the=0A= # GNU General Public License for more details.=0A= #=0A= # You should have received a copy of the GNU General Public License=0A= # along with this program; if not, write to the Free Software=0A= # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=0A= #=0A= =0A= #=0A= # current version of cron=0A= #=0A= VERSION=3D 2.9.3=0A= =0A= #=0A= # The following three settings affect the local security.=0A= # Change them, to use your own local settings and don't tell about!=0A= #=0A= # PWBUFSIZ should be greater than 128.=0A= #=0A= # PWBUFPOS should be greater than 32 and less than PWBUFPOS - 32.=0A= #=0A= # PWKEYWORD should be exactly 8 characters long.=0A= #=0A= # PWBUFSIZ=3D -DPWBUFSIZ=3D500=0A= # PWBUFPOS=3D -DPWBUFPOS=3D238=0A= # PWKEYWORD=3D -DPWKEYWORD=3D"\"\340\221\172\033\061\105\304\057\""=0A= #=0A= PWBUFSIZ=3D -DPWBUFSIZ=3D512=0A= PWBUFPOS=3D -DPWBUFPOS=3D256=0A= PWKEYWORD=3D -DPWKEYWORD=3D"\"\107\056\114\273\146\231\033\266\""=0A= =0A= EXEEXT=3D.exe=0A= #EXEEXT=3D=0A= =0A= PREFIX=3D/usr/local=0A= BINDIR=3D$(PREFIX)/bin=0A= SBINDIR=3D$(PREFIX)/sbin=0A= MANDIR=3D$(PREFIX)/man=0A= =0A= CRONDIR=3D/var/cron=0A= =0A= CXX=3Dg++ -g=0A= CXXFLAGS=3D$(PWBUFSIZ) $(PWBUFPOS) $(PWKEYWORD)=0A= LDFLAGS=3D =0A= LIBS=3D-L/usr/lib -lpopt=0A= =0A= COMMONOBJ=3D CString.o \=0A= cronPW.o \=0A= crontab.o \=0A= crontabList.o \=0A= entry.o=0A= =0A= CRYPTOBJ=3D encrypt.o=0A= =0A= CRONOBJ=3D cron.o service.o $(COMMONOBJ) $(CRYPTOBJ)=0A= =0A= CRONTABOBJ=3D crontabApp.o $(COMMONOBJ) $(CRYPTOBJ)=0A= =0A= all: cron$(EXEEXT) crontab$(EXEEXT)=0A= =0A= cron$(EXEEXT): $(CRONOBJ)=0A= $(CXX) $(LDFLAGS) -o $@ $(CRONOBJ) $(LIBS)=0A= =0A= crontab$(EXEEXT): $(CRONTABOBJ)=0A= $(CXX) $(LDFLAGS) -o $@ $(CRONTABOBJ) -lnetapi32=0A= =0A= cronPW.o: encrypt.h=0A= cron.o crontabList.o: crontabList.h=0A= cron.o crontabApp.o crontabList.o cronPW.o: cronPW.h=0A= cron.o crontabApp.o crontabList.o crontab.o: crontab.h=0A= cron.o crontabApp.o crontabList.o crontab.o entry.o: entry.h=0A= cron.o crontabApp.o $(COMMONOBJ): CString.h Makefile=0A= =0A= install: $(SBINDIR)/cron.exe $(BINDIR)/crontab$(EXEEXT)=0A= if [ ! -d $(CRONDIR) ]; then \=0A= mkdir $(CRONDIR); \=0A= cp deny $(CRONDIR); \=0A= fi=0A= =0A= #Don't use $(EXEEXT) here!=0A= $(SBINDIR)/cron.exe: cron$(EXEEXT)=0A= cp cron$(EXEEXT) $@=0A= -chmod 775 $@=0A= =0A= $(BINDIR)/crontab$(EXEEXT): crontab$(EXEEXT)=0A= cp crontab$(EXEEXT) $@=0A= -chmod 775 $@=0A= =0A= docinstall: $(MANDIR)/man1/crontab.1 $(MANDIR)/man5/crontab.5 = $(MANDIR)/man8/cron.8=0A= =0A= $(MANDIR)/man1/crontab.1:=0A= cp crontab.1 $(MANDIR)/man1=0A= -chmod 664 $@=0A= =0A= $(MANDIR)/man5/crontab.5:=0A= cp crontab.5 $(MANDIR)/man5=0A= -chmod 664 $@=0A= =0A= $(MANDIR)/man8/cron.8:=0A= cp cron.8 $(MANDIR)/man8=0A= -chmod 664 $@=0A= =0A= clean:=0A= -rm -f cron$(EXEEXT) crontab$(EXEEXT) *.o *.core *.tar.gz=0A= =0A= archive: cron-$(VERSION).src.tar.gz cron-$(VERSION).bin.tar.gz=0A= =0A= ARCLIST=3D cron-$(VERSION)/COPYING \=0A= cron-$(VERSION)/ChangeLog \=0A= cron-$(VERSION)/Makefile \=0A= cron-$(VERSION)/*.c \=0A= cron-$(VERSION)/*.cc \=0A= cron-$(VERSION)/*.h \=0A= cron-$(VERSION)/*.[158] \=0A= cron-$(VERSION)/deny=0A= =0A= cron-$(VERSION).src.tar.gz: Makefile=0A= cd ..; tar czf cron-$(VERSION)/$@ $(ARCLIST)=0A= =0A= BINARCLIST=3D $(SBINDIR)/cron$(EXEEXT) \=0A= $(BINDIR)/crontab$(EXEEXT) \=0A= $(MANDIR)/man1/crontab.1 \=0A= $(MANDIR)/man5/crontab.5 \=0A= $(MANDIR)/man8/cron.8 \=0A= $(CRONDIR)/deny=0A= =0A= cron-$(VERSION).bin.tar.gz: Makefile $(BINARCLIST)=0A= tar czf $@ $(BINARCLIST)=0A= =0A= ------=_NextPart_000_0012_01C0D799.8A49BBB0 Content-Type: application/octet-stream; name="cron.cc" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="cron.cc" /* cron.cc - main source of cron(8)=0A= Copyright (C) 1998 Corinna Vinschen =0A= =0A= This program is free software; you can redistribute it and/or modify=0A= it under the terms of the GNU General Public License as published by=0A= the Free Software Foundation; either version 2, or (at your option)=0A= any later version.=0A= =0A= This program is distributed in the hope that it will be useful,=0A= but WITHOUT ANY WARRANTY; without even the implied warranty of=0A= MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the=0A= GNU General Public License for more details.=0A= =0A= You should have received a copy of the GNU General Public License=0A= along with this program; if not, write to the Free Software=0A= Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */=0A= =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= =0A= #include "CString.h"=0A= #include "entry.h"=0A= #include "crontab.h"=0A= #include "cronPW.h"=0A= #include "crontabList.h"=0A= #include "service.h"=0A= =0A= int work_main(void);=0A= static void usage(poptContext optCon, FILE * f, char * name);=0A= static void help(poptContext optCon, FILE * f, char * name);=0A= static void version(poptContext optCon, FILE * f, char * name);=0A= static void license(poptContext optCon, FILE * f, char * name);=0A= =0A= =0A= LPSECURITY_ATTRIBUTES=0A= NullSA (void)=0A= {=0A= static PSECURITY_DESCRIPTOR pSDNull;=0A= static SECURITY_ATTRIBUTES SA;=0A= =0A= if (!pSDNull)=0A= {=0A= pSDNull =3D (PSECURITY_DESCRIPTOR)=0A= LocalAlloc (LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);=0A= InitializeSecurityDescriptor (pSDNull, = SECURITY_DESCRIPTOR_REVISION);=0A= SetSecurityDescriptorDacl (pSDNull, TRUE, NULL, FALSE);=0A= }=0A= SA.nLength =3D sizeof SA;=0A= SA.lpSecurityDescriptor =3D pSDNull; // Security-Descriptor mit leerer = ACL=0A= =0A= SA.bInheritHandle =3D TRUE; // Handle wird an Subprozesse vererbt=0A= =0A= return &SA;=0A= }=0A= =0A= int=0A= OpenCronFile (const char *name)=0A= {=0A= return open(name, O_CREAT | O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR);=0A= }=0A= =0A= bool=0A= WriteTimeStamp (int fdOut, int fdErr)=0A= {=0A= time_t t =3D time ((time_t *) 0);=0A= =0A= write (fdOut, "\ncron: ", 7);=0A= write (fdOut, ctime (&t), 25);=0A= write (fdErr, "\ncron: ", 7);=0A= write (fdErr, ctime (&t), 25);=0A= return false;=0A= }=0A= =0A= void=0A= WriteError (int fdErr, const char *text)=0A= {=0A= DWORD written;=0A= CString ErrTxt;=0A= =0A= ErrTxt.Format ("%d\n", GetLastError ());=0A= write (fdErr, text, strlen (text));=0A= write (fdErr, ": ", 2);=0A= write (fdErr, ErrTxt, ErrTxt.GetLength ());=0A= }=0A= =0A= LPSTARTUPINFO=0A= StartupInfo (int fdOut, int fdErr)=0A= {=0A= static STARTUPINFO si;=0A= =0A= memset (&si, 0, sizeof si);=0A= si.cb =3D sizeof si;=0A= si.dwFlags =3D STARTF_FORCEOFFFEEDBACK | STARTF_USESTDHANDLES;=0A= si.hStdOutput =3D (HANDLE) get_osfhandle (fdOut);=0A= si.hStdError =3D (HANDLE) get_osfhandle (fdErr);=0A= return &si;=0A= }=0A= =0A= time_t=0A= WaitForNextMinute (time_t last)=0A= {=0A= time_t now;=0A= =0A= do=0A= {=0A= Sleep (5000L);=0A= now =3D time ((time_t *) 0);=0A= }=0A= while (now / 60 =3D=3D last / 60);=0A= return now;=0A= }=0A= =0A= HANDLE=0A= CreateUserToken (const char *user, const char *pwd, int fdOut, int fdErr)=0A= {=0A= HANDLE hUser;=0A= =0A= if (! LogonUser ((char *) user, ".", (char *) pwd,=0A= LOGON32_LOGON_INTERACTIVE,=0A= LOGON32_PROVIDER_DEFAULT,=0A= &hUser))=0A= {=0A= WriteTimeStamp (fdOut, fdErr);=0A= WriteError (fdErr, "LogonUser");=0A= return NULL;=0A= }=0A= return hUser;=0A= }=0A= =0A= =0A= int=0A= main (int argc, char **argv)=0A= {=0A= char *myname;=0A= int install =3D 0, remove =3D 0;=0A= poptContext optCon;=0A= const char ** rest;=0A= int rc;=0A= int ec =3D 0;=0A= int c;=0A= int debug =3D 0;=0A= =0A= struct poptOption generalOptionsTable[] =3D {=0A= { "quiet", 'q', POPT_ARG_NONE, NULL, 'q', \=0A= "Quiet mode", NULL},=0A= { "install-as-service", '\0', POPT_ARG_NONE, NULL, 'I', \=0A= "Install as a windows service.", NULL},=0A= { "remove-as-service", '\0', POPT_ARG_NONE, NULL, 'R', \=0A= "Remove as a windows service.", NULL},=0A= { "service", 's', POPT_ARG_NONE, NULL, 's', \=0A= "Run in service mode. This option should ONLY be used "=0A= "from within the NT/2K service manager system; do NOT "=0A= "use it in ANY other context -- shortcuts, .bat files, "=0A= "manual command-line entry, etc.", NULL},=0A= { "debug", 'd', POPT_ARG_NONE, NULL, 'd', \=0A= "Print execution trace to stderr (or syslog if in service = mode)", NULL},=0A= { NULL, '\0', 0, NULL, 0, NULL, NULL }=0A= };=0A= =0A= struct poptOption helpOptionsTable[] =3D {=0A= { "help", '?', POPT_ARG_NONE, NULL, '?', \=0A= "Show this help message", NULL},=0A= { "usage", '\0', POPT_ARG_NONE, NULL, 'u', \=0A= "Display brief usage message", NULL},=0A= { "version", '\0', POPT_ARG_NONE, NULL, 'v', \=0A= "Display version information", NULL},=0A= { "license", '\0', POPT_ARG_NONE, NULL, 'l', \=0A= "Display licensing information", NULL},=0A= { NULL, '\0', 0, NULL, 0, NULL, NULL }=0A= };=0A= =0A= struct poptOption opt[] =3D {=0A= { NULL, '\0', POPT_ARG_INCLUDE_TABLE, generalOptionsTable, 0, \=0A= "General options", NULL },=0A= { NULL, '\0', POPT_ARG_INCLUDE_TABLE, helpOptionsTable, 0, \=0A= "Help options", NULL },=0A= { NULL, '\0', 0, NULL, 0, NULL, NULL }=0A= };=0A= =0A= if (! (myname =3D strrchr (argv[0], '\\'))=0A= && ! (myname =3D strrchr (argv[0], '/')))=0A= myname =3D argv[0];=0A= else=0A= ++myname;=0A= if (strrchr (myname, '.'))=0A= *strrchr (myname, '.') =3D '\0';=0A= =0A= optCon =3D poptGetContext(NULL, argc, (const char **) argv, opt, 0);=0A= =0A= while ((rc =3D poptGetNextOpt(optCon)) > 0) {=0A= switch (rc) {=0A= case '?': help(optCon, stderr, myname);=0A= goto exit;=0A= =0A= case 'v': version(optCon, stderr, myname);=0A= goto exit;=0A= =0A= case 'l': license(optCon, stderr, myname);=0A= goto exit;=0A= =0A= case 'd': debug =3D 1;=0A= break;=0A= =0A= case 'I': install =3D 1;=0A= break;=0A= =0A= case 'R': remove =3D 1;=0A= break;=0A= =0A= case 's': service =3D 1;=0A= break;=0A= =0A= default: usage(optCon, stderr, myname);=0A= goto exit;=0A= }=0A= }=0A= /*=0A= if (rc < -1 ) {=0A= log_message(stderr, LOG_ERR, "%s: bad argument %s: %s",myname, = poptBadOption(optCon, POPT_BADOPTION_NOALIAS),=0A= poptStrerror(rc));=0A= ec =3D 2;=0A= goto exit;=0A= }=0A= =0A= if (install && remove) {=0A= log_message(stderr, LOG_ERR, =0A= "%s: can't specify both --install-as-service and = --remove-as-service\nNo action taken.", myname);=0A= ec =3D 2;=0A= goto exit;=0A= }=0A= */=0A= rest =3D poptGetArgs(optCon);=0A= if (rest) {=0A= char buf[2000];=0A= int count;=0A= count =3D snprintf(buf, 2000, "Extra args ignored: ");=0A= while (*rest) =0A= count +=3D snprintf(buf + count, 2000 - count, "%s ", *rest++);=0A= // log_message(stderr, LOG_WARNING, buf);=0A= }=0A= =0A= if (!debug && !install && !remove && !service)=0A= switch (pid_t pid =3D fork ())=0A= {=0A= case -1:=0A= perror (myname);=0A= return 1;=0A= case 0:=0A= close (0);=0A= close (1);=0A= close (2);=0A= setsid ();=0A= break;=0A= =0A= default:=0A= return 0;=0A= }=0A= =0A= // install cron as service =0A= if (install) {=0A= ec =3D install_as_service(myname, 1);=0A= if (!ec) {=0A= ec =3D install_reg_entries(myname, 1);=0A= if (ec)=0A= remove_as_service(myname, 1);=0A= }=0A= }=0A= else if (remove) {=0A= ec =3D remove_as_service(myname, 1);=0A= }=0A= else if (service) {=0A= ec =3D start_service();=0A= }=0A= else {=0A= work_main();=0A= ec =3D 0;=0A= }=0A= exit:=0A= poptFreeContext(optCon);=0A= // closelog();=0A= return(ec);=0A= }=0A= =0A= =0A= int work_main(void)=0A= {=0A= CCrontabList cronlist;=0A= time_t now =3D time ((time_t *) 0);=0A= =0A= while (now =3D WaitForNextMinute (now))=0A= {=0A= CLEntry *listentry;=0A= CEntry *entry;=0A= =0A= cronlist.Open (GetCronDir ());=0A= while (listentry =3D cronlist.NextEntry ())=0A= {=0A= bool first =3D true;=0A= =0A= int fdStdOut =3D OpenCronFile (listentry->home + "/.cron.stdout");=0A= int fdStdErr =3D OpenCronFile (listentry->home + "/.cron.stderr");=0A= =0A= while (entry =3D listentry->crontab.NextEntry ())=0A= if (*entry =3D=3D now)=0A= {=0A= if (first)=0A= first =3D WriteTimeStamp (fdStdOut, fdStdErr);=0A= switch (pid_t pid =3D fork ())=0A= {=0A= case -1: // Error=0A= WriteError (fdStdErr, "error invoking fork");=0A= break;=0A= =0A= case 0: // Child=0A= HANDLE hUser;=0A= int pd[2];=0A= =0A= putenv ("LOGNAME=3D" + listentry->user);=0A= putenv ("USER=3D" + listentry->user);=0A= putenv ("HOME=3D" + listentry->home);=0A= putenv (CString ("PATH=3D/bin:/usr/bin:") + getenv ("PATH"));=0A= putenv ("SHELL=3D/bin/sh");=0A= =0A= if (pipe (pd))=0A= {=0A= WriteError (fdStdErr, "error creating pipe");=0A= exit (1);=0A= }=0A= dup2 (fdStdOut, 1);=0A= dup2 (fdStdErr, 2);=0A= chdir (listentry->home);=0A= switch (fork ())=0A= {=0A= case -1: // Error=0A= WriteError (fdStdErr, "error invoking fork (2)");=0A= break;=0A= =0A= case 0: // Child=0A= dup2 (pd[0], 0);=0A= close (pd[0]);=0A= close (pd[1]);=0A= =0A= if ((hUser =3D CreateUserToken (listentry->user,=0A= cronlist.GetPwd (listentry->user),=0A= fdStdOut,=0A= fdStdErr)) =3D=3D INVALID_HANDLE_VALUE)=0A= exit (1);=0A= sexecl (hUser,=0A= "/bin/sh", "sh",=0A= "-c", entry->cmd.c_str (),=0A= NULL);=0A= WriteError (fdStdErr, "error invoking sexecl");=0A= break;=0A= =0A= default: // Parent=0A= close (pd[0]);=0A= if (! entry->std_in.IsEmpty ())=0A= write (pd[1], entry->std_in,=0A= entry->std_in.GetLength ());=0A= close (pd[1]);=0A= break;=0A= }=0A= return 0;=0A= /*NOTREACHED*/=0A= =0A= default: // Parent=0A= waitpid (pid, NULL, 0);=0A= break;=0A= }=0A= }=0A= close (fdStdOut);=0A= close (fdStdErr);=0A= }=0A= =0A= }=0A= cronlist.Close ();=0A= }=0A= =0A= static void printTopDescription(FILE * f, char * name)=0A= {=0A= char buf[512];=0A= fprintf(f, "%s : Cygwin Cron Version %s (c) 1998 PCH/LLA, Changes (c) = 2001 CSW\n", =0A= name, getVersion(buf, 512));=0A= fprintf(f, " This daemon provides crontab functionality.\n\n");=0A= }=0A= =0A= static void printLicense(FILE * f, char * name)=0A= {=0A= fprintf(f, "This program is free software; you can redistribute it = and/or\n");=0A= fprintf(f, "modify it under the terms of the GNU General Public = License\n");=0A= fprintf(f, "as published by the Free Software Foundation; either = version 2\n");=0A= fprintf(f, "of the License, or (at your option) any later version.\n");=0A= fprintf(f, "\n");=0A= fprintf(f, "This program is distributed in the hope that it will be = useful,\n");=0A= fprintf(f, "but WITHOUT ANY WARRANTY; without even the implied = warranty of\n");=0A= fprintf(f, "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See = the\n");=0A= fprintf(f, "GNU General Public License for more details.\n");=0A= fprintf(f, "\n");=0A= fprintf(f, "You should have received a copy of the GNU General Public = License\n");=0A= fprintf(f, "along with this program; if not, write to the Free = Software\n");=0A= fprintf(f, "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA = 02111-1307, USA.\n");=0A= fprintf(f, "\n");=0A= fprintf(f, "See the COPYING file for license information.\n");=0A= }=0A= =0A= static void usage(poptContext optCon, FILE * f, char * name)=0A= {=0A= poptPrintUsage(optCon, f, 0);=0A= }=0A= =0A= static void help(poptContext optCon, FILE * f, char * name)=0A= {=0A= printTopDescription(f, name);=0A= poptPrintHelp(optCon, f, 0);=0A= }=0A= =0A= static void version(poptContext optCon, FILE * f, char * name)=0A= {=0A= printTopDescription(f, name);=0A= }=0A= =0A= static void license(poptContext optCon, FILE * f, char * name)=0A= {=0A= printTopDescription(f, name);=0A= printLicense(f, name);=0A= }=0A= ------=_NextPart_000_0012_01C0D799.8A49BBB0 Content-Type: text/plain; charset=us-ascii -- Want to unsubscribe from this list? Check out: http://cygwin.com/ml/#unsubscribe-simple ------=_NextPart_000_0012_01C0D799.8A49BBB0--