Mail Archives: cygwin/2001/05/08/02:36:31
------=_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 <stdio.h>=0A=
#include <unistd.h>=0A=
#include <stdlib.h>=0A=
#include <signal.h>=0A=
#include <string.h>=0A=
#include <stdarg.h>=0A=
#include <windows.h>=0A=
#include <exceptions.h>=0A=
#include <sys/cygwin.h>=0A=
#include <sys/wait.h>=0A=
#include <syslog.h>=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 <corinna DOT vinschen AT cityweb DOT de>=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 <corinna DOT vinschen AT cityweb DOT de>=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 <sys/types.h>=0A=
#include <sys/stat.h>=0A=
#include <sys/wait.h>=0A=
#include <sys/cygwin.h>=0A=
#include <io.h>=0A=
#include <stdio.h>=0A=
#include <stdlib.h>=0A=
#include <unistd.h>=0A=
#include <getopt.h>=0A=
#include <time.h>=0A=
#include <fcntl.h>=0A=
#include <process.h>=0A=
#include <windows.h>=0A=
#include <popt.h>=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--
- Raw text -