|
Home - Old Man Programmer
| Displaying projects/sac/writetmp.c
/* $Copyright: $
* Copyright (c) 1998 by Steve Baker (ice@mama.indstate.edu)
* All Rights reserved
*
* This software is provided as is without any express or implied
* warranties, including, without limitation, the implied warranties
* of merchant-ability and fitness for a particular purpose.
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef SOLARIS
#include <utmpx.h>
#else
#include <utmp.h>
#endif
#include <string.h>
#include <sys/file.h>
#include <sys/types.h>
#include <fcntl.h>
#include <time.h>
static char *version = "$Version: $ writetmp v1.0 (c) 1998 by Steve Baker $";
#ifdef SOLARIS
#define _PATH_WTMP WTMPX_FILE
#else
#ifndef _PATH_WTMP
#define _PATH_WTMP "/var/log/wtmp"
#endif
#endif
#ifdef SOLARIS
#define UT_UNKNOWN 0
#define UT_NAMESIZE 32
#define UT_LINESIZE 32
#define UT_HOSTSIZE 257
#define utmp utmpx
#define ut_time ut_tv.tv_sec
#endif
struct tacacs3_utmp {
char ut_line[8];
char ut_user[8];
char ut_host[16];
time_t ut_tactime;
};
struct tacacs4_utmp {
char ut_line[8];
char ut_user[8];
char ut_host[16];
time_t ut_tactime;
char ut_comment[16];
};
struct uttypes {
char *name;
int val;
} uttypes[] = {
{"unknown", UT_UNKNOWN},
{"runlevel", RUN_LVL},
{"boottime", BOOT_TIME},
{"newtime", NEW_TIME},
{"oldtime", OLD_TIME},
{"init", INIT_PROCESS},
{"login", LOGIN_PROCESS},
{"user", USER_PROCESS},
{"dead", DEAD_PROCESS},
{NULL, 0}
};
enum { TRUE=1, FALSE=0 };
enum { SHUTDOWN=0, HALT, REBOOT, BOOTTIME, RUNLEVEL, OLDTIME, NEWTIME };
struct wtype {
char *command;
char *user;
char *line;
char *id;
short ut_type;
} wtype[] = {
{"shutdown", "shutdown", "~", "~~", RUN_LVL},
{"halt", "shutdown", "~", "~~", RUN_LVL},
{"reboot", "shutdown", "~", "~~", RUN_LVL},
{"boottime", "reboot", "~", "~~", BOOT_TIME},
{"runlevel", "runlevel", "~", "~~", RUN_LVL},
{"oldtime", "", "", "|", OLD_TIME},
{"newtime", "", "", "{", NEW_TIME},
{NULL, NULL, NULL, NULL, 0}
};
void usage(int);
int doit(int, char *, char *, char *, short, char *, pid_t);
int doit_tacacs3(int, char *, char *, char *);
int doit_tacacs4(int, char *, char *, char *, char *);
int fd;
/*
* writetmp [-w wtmp] [-X[3|4]] [-u user] [-l line] [-h host] [-t type]
* [-i id] [-p pid] [-c comment] [entry-type] [--help] [--version]
*/
int main(int argc, char **argv)
{
char *file = _PATH_WTMP, tacacs3 = FALSE, tacacs4 = FALSE;
char *user = NULL, *line = NULL, *host = NULL, *id = NULL, *comment = NULL;
pid_t pid = 0;
short type = 0;
int i, j, n, r;
int command = -1;
for(n=i=1;i<argc;i=n) {
n++;
if (argv[i][0] == '-') {
for(j=1;argv[i][j];j++) {
switch (argv[i][j]) {
case 'w':
file = argv[n++];
break;
case 'X':
if (argv[i][j+1] == '4') {
j++;
tacacs4 = TRUE;
} else if (argv[i][j+1] == '3') {
j++;
tacacs3 = TRUE;
} else tacacs3 = TRUE;
break;
case '-':
if (j == 1) {
if (!strcmp("--help",argv[i])) usage(4);
if (!strcmp("--version",argv[i])) usage(5);
}
case 'u': /* user */
user = argv[n++];
break;
case 'l': /* line */
line = argv[n++];
break;
case 'h': /* host */
host = argv[n++];
break;
case 't': /* type */
for(r=0;uttypes[r].name;r++)
if (!strcmp(uttypes[r].name,argv[n])) {
type = uttypes[r].val;
break;
}
if (uttypes[r].name == NULL) type = atoi(argv[n]);
n++;
break;
case 'i': /* id */
id = argv[n++];
break;
case 'p': /* pid */
pid = atoi(argv[n++]);
break;
case 'c': /* comment */
comment = argv[n++];
break;
default:
usage(1);
}
}
} else {
for(j=0;wtype[j].command;j++)
if (!strcmp(argv[i],wtype[j].command)) {
command = j;
break;
}
}
}
if (!strcmp(file,"-")) fd=1;
else if ((fd = open(file,O_WRONLY | O_APPEND | O_CREAT,0777)) < 0) usage(2);
if (tacacs4) r=doit_tacacs4(command,line,user,host,comment);
else if (tacacs3) r=doit_tacacs3(command,line,user,host);
else r=doit(command,line,user,host,type,id,pid);
close(fd);
return r;
}
int doit(int command, char *line, char *user, char *host, short type, char *id, pid_t pid)
{
struct utmp u;
memset(&u,0,sizeof(u));
if (command >= 0) {
strncpy(u.ut_line,wtype[command].line,UT_LINESIZE);
strncpy(u.ut_user,wtype[command].user,UT_NAMESIZE);
strncpy(u.ut_id,wtype[command].id,2);
u.ut_type = wtype[command].ut_type;
} else {
if (line) strncpy(u.ut_line, line, UT_LINESIZE);
if (host) strncpy(u.ut_host, host, UT_HOSTSIZE);
if (user) strncpy(u.ut_user, user, UT_NAMESIZE);
if (id) strncpy(u.ut_id, id, 2);
u.ut_type = type;
u.ut_pid = pid;
}
u.ut_time = time(0);
return write(fd,&u,sizeof(u)) < 0;
}
int doit_tacacs3(int command, char *line, char *user, char *host)
{
struct tacacs3_utmp u;
memset(&u,0,sizeof(u));
if (command >= 0) {
strncpy(u.ut_line,wtype[command].line,UT_LINESIZE);
strncpy(u.ut_user,wtype[command].user,UT_NAMESIZE);
} else {
if (line) strncpy(u.ut_line, line, 8);
if (user) strncpy(u.ut_user, user, 8);
if (host) strncpy(u.ut_host, host, 16);
}
u.ut_tactime = time(0);
return write(fd,&u,sizeof(u)) < 0;
}
int doit_tacacs4(int command, char *line, char *user, char *host, char *comment)
{
struct tacacs4_utmp u;
memset(&u,0,sizeof(u));
if (command) {
strncpy(u.ut_line,wtype[command].line,UT_LINESIZE);
strncpy(u.ut_user,wtype[command].user,UT_NAMESIZE);
} else {
if (line) strncpy(u.ut_line, line, 8);
if (user) strncpy(u.ut_user, user, 8);
if (host) strncpy(u.ut_host, host, 16);
if (comment) strncpy(u.ut_comment, comment, 16);
}
u.ut_tactime = time(0);
return write(fd,&u,sizeof(u)) < 0;
}
void usage(n)
int n;
{
switch (n) {
case 1:
fprintf(stderr,"usage: writetmp [-w wtmp|-] [-X[3|4]] [-u user] [-l line] [-h host] [-i id]\n\t[-t type] [-p pid] [-c comment] [--help] [--version] [entry-type]\n");
break;
case 2:
fprintf(stderr,"writetmp: Error opening wtmp file for writing.\n");
break;
case 4:
fprintf(stderr,"usage: writetmp [-w wtmp|-] [-X[3|4]] [-u user] [-l line] [-h host] [-i id]\n\t[-t type] [-p pid] [-c comment] [--help] [--version] [entry-type]\n");
fprintf(stderr," -w wtmp|- Write to alternate wtmp file.\n");
fprintf(stderr," -X[3] Write in tacacs 3.x wtmp format.\n");
fprintf(stderr," -X4 Write in tacacs 4.0 wtmp format.\n");
fprintf(stderr," -u user Specify username.\n");
fprintf(stderr," -l line Specify the line.\n");
fprintf(stderr," -h host Specify the hostname.\n");
fprintf(stderr," -i id Specify the init id.\n");
fprintf(stderr," -t type Specify the type of entry.\n");
fprintf(stderr," -p pid Specify the pid number.\n");
fprintf(stderr," -c comment Specify the comment.\n");
fprintf(stderr," --help Print this help message.\n");
fprintf(stderr," --version Print the version of rawtmp.\n");
fprintf(stderr," Entry-types:\n");
fprintf(stderr," shutdown Indicates the system is shutting down.\n");
fprintf(stderr," reboot Alias for shutdown.\n");
fprintf(stderr," halt Alias for shutdown.\n");
fprintf(stderr," boottime Indicates the system is booting.\n");
fprintf(stderr," oldtime Indicates the time is about to change.\n");
fprintf(stderr," newtime Indicates the time has changed.\n");
fprintf(stderr," runlevel Indicates the runlevel has changed.\n");
break;
case 5:
{
char *v = version+12;
printf("%.*s\n",(int)strlen(v)-1,v);
exit(0);
}
}
exit(1);
}
|