static char rcsid[] = "@(#)$Id: reghelper.c,v 1.8 2006/04/09 07:37:30 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.8 $ $State: Exp $
*
* Author: Kari Hurtta <hurtta+elm@posti.FMI.FI> (was hurtta+elm@ozone.FMI.FI)
*****************************************************************************/
#include "defs_major.h"
#include "patchlevel.h"
#include "reghelper.h"
/* Protocol in PIPE:
*
* file descriptor given on $ELM_INSTALLER
* installer root given on $ELM_ROOT
*
* filenames are relative to $ELM_ROOT
*
*
* -- copy file
*
* 'F' user group mode filename '\n'
*
* -- create directory
*
* 'M' user group mode filename '\n'
*
* -- execute
* {n} user group mode filename '\n'
* {n} user group mode filename'\n'
*
* 'E' filename {n} xx yy {n} '\n'
*
* -- config file touched on replay time
*
* 'C' user group mode filename'\n'
*
* -- remove files
*
* 'R' file file file '\n'
*
* -- link file
*
* 'L' file file '\n'
*
*/
#include <errno.h>
#ifndef ANSI_C
extern int errno;
#endif
void reghelper_init()
{
char * register_pipe = getenv("ELM_INSTALLER");
char * installer_root = getenv("ELM_ROOT");
int fd;
struct stat X;
if (installer_root && 0 != strcmp(installer_root,"/")) {
fprintf(stderr,
"%s does not support $ELM_ROOT=%s\n",
program_name,installer_root);
exit(1);
}
if (!register_pipe) {
register_fd = -1;
return;
}
fd = atoi(register_pipe);
if (fd < 1) {
fprintf(stderr,"%s: $ELM_INSTALLER=%s invalid\n",
program_name,register_pipe);
exit (1); /* FAILURE */
}
if (fstat(fd,&X) < 0) {
fprintf(stderr,"%s: $ELM_INSTALLER=%s invalid\n",
program_name,register_pipe);
exit (1); /* FAILURE */
}
register_fd = fd;
register_module = getenv("ELM_MODULE");
}
void log_config(file)
char *file;
{
/* Skip '/' on front ... */
while ('/' == file[0])
file++;
if (register_fd != -1)
log_it("C",file,"-","-",0, register_module);
}
void log_it(letter,target_r,user,group,mode, module)
char * letter;
char * target_r;
char * user;
char * group;
int mode;
char * module;
{
int l_letter = strlen(letter);
int l_target = strlen(target_r);
int l_user = strlen(user);
int l_group = strlen(group);
int l_module = module ? strlen(module) : 0;
char buffer[ MAX_PIPE_LOG];
char *ptr;
char mode_s[6];
int L = 17 + l_letter + l_target + l_user + l_group + l_module;
sprintf(mode_s,"%05o",mode);
if (L > MAX_PIPE_LOG-2) {
fprintf(stderr,"%s: Can't register file, string too long: %d\n",
program_name,L);
exit(1);
}
ptr = buffer;
if (module) {
add_to_buffer(buffer, sizeof buffer,&ptr,"m",1);
add_to_buffer(buffer, sizeof buffer,&ptr,module,l_module);
}
add_to_buffer(buffer, sizeof buffer,&ptr,letter,l_letter);
add_to_buffer(buffer, sizeof buffer,&ptr,user,l_user);
add_to_buffer(buffer, sizeof buffer,&ptr,group,l_group);
add_to_buffer(buffer, sizeof buffer,&ptr,mode_s,5);
add_to_buffer(buffer, sizeof buffer,&ptr,target_r,l_target);
*ptr++ = '\n'; /* Terminating NL on line */
L = ptr - buffer;
if (L > MAX_PIPE_LOG-2) {
fprintf(stderr,"%s: Can't register file, string too long: %d\n",
program_name,L);
exit(1);
}
write_once(register_fd,buffer,L);
}
void write_once(fd,buffer,L)
int fd;
char *buffer;
int L;
{
int n;
/* We have better to able write whole string at ONCE,
or otherwise two different writes from different processes
are mixed on pipe ... (ie. if paraller make)
*/
again:
n = write(fd,buffer,L);
if (n < 0) {
if (EINTR == errno)
goto again;
fprintf(stderr,"%s: Can't register file or command, write to fd %d failed\n",
program_name,fd);
exit(1);
}
if (n != L) {
fprintf(stderr,"%s: Can't register file or command, incomplete write to fd %d : %d bytes written (expected %d)\n",
program_name,fd, n, L);
exit(1);
}
}
void add_to_buffer(buffer,blen,ptr,str,s_len)
char *buffer;
size_t blen;
char **ptr;
char *str;
int s_len;
{
char *p = *ptr;
char *s = str;
int abt = 0;
if (p < buffer || p >= buffer +blen) {
fprintf(stderr,"%s: out of range!!\n",program_name);
exit(1);
}
for (p = *ptr, s = str;
p < buffer + blen && s < str + s_len;
p++, s++) {
*p = *s;
}
if (*s != '\0') {
fprintf(stderr,
"%s: incorrect s_len=%d (or out of buffer), str=%s!!\n",
program_name, s_len,str);
abt = 1;
}
if (p == buffer +blen) {
fprintf(stderr,
"%s: out of buffer\n",
program_name);
abt = 1;
}
if (abt)
exit(abt);
*p++ = '\0';
*ptr = p;
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1