version 1.11, 2007/03/23 03:43:46 |
version 1.12, 2007/03/23 05:08:03 |
|
|
|
|
#include "atomicio.h" |
#include "atomicio.h" |
|
|
int init(void); |
void init(void); |
int prompt(void); |
int prompt(void); |
int send_file(const char *, int dst); |
int send_file(const char *, int dst); |
int sendmail(const char *); |
int sendmail(const char *); |
|
|
struct passwd *pw; |
struct passwd *pw; |
char os[BUFSIZ], rel[BUFSIZ], mach[BUFSIZ]; |
char os[BUFSIZ], rel[BUFSIZ], mach[BUFSIZ]; |
char *fullname; |
char *fullname; |
|
char *tmppath; |
|
int wantcleanup; |
|
|
void |
__dead void |
usage(void) |
usage(void) |
{ |
{ |
fprintf(stderr, "usage: sendbug [-LPV]\n"); |
fprintf(stderr, "usage: sendbug [-LPV]\n"); |
|
exit(1); |
} |
} |
|
|
|
void |
|
cleanup() |
|
{ |
|
if (wantcleanup && tmppath && unlink(tmppath) == -1) |
|
warn("unlink"); |
|
} |
|
|
|
|
int |
int |
main(int argc, char *argv[]) |
main(int argc, char *argv[]) |
{ |
{ |
const char *editor, *tmpdir; |
const char *editor, *tmpdir; |
char *argp[] = {"sh", "-c", NULL, NULL}, *tmppath = NULL, *pr_form; |
char *argp[] = {"sh", "-c", NULL, NULL}, *pr_form; |
int ch, c, fd, ret = 1; |
int ch, c, fd, ret = 1; |
struct stat sb; |
struct stat sb; |
time_t mtime; |
time_t mtime; |
|
|
printf("%s\n\n", categories); |
printf("%s\n\n", categories); |
exit(0); |
exit(0); |
case 'P': |
case 'P': |
if (init() == -1) |
init(); |
exit(1); |
|
template(stdout); |
template(stdout); |
exit(0); |
exit(0); |
case 'V': |
case 'V': |
|
|
exit(0); |
exit(0); |
default: |
default: |
usage(); |
usage(); |
exit(1); |
|
} |
} |
|
|
if (argc > 1) { |
if (argc > 1) { |
usage(); |
usage(); |
exit(1); |
|
} |
} |
|
|
if ((tmpdir = getenv("TMPDIR")) == NULL || tmpdir[0] == '\0') |
if ((tmpdir = getenv("TMPDIR")) == NULL || tmpdir[0] == '\0') |
tmpdir = _PATH_TMP; |
tmpdir = _PATH_TMP; |
if (asprintf(&tmppath, "%s%sp.XXXXXXXXXX", tmpdir, |
if (asprintf(&tmppath, "%s%sp.XXXXXXXXXX", tmpdir, |
tmpdir[strlen(tmpdir) - 1] == '/' ? "" : "/") == -1) { |
tmpdir[strlen(tmpdir) - 1] == '/' ? "" : "/") == -1) { |
warn("asprintf"); |
err(1, "asprintf"); |
goto quit; |
|
} |
} |
if ((fd = mkstemp(tmppath)) == -1) |
if ((fd = mkstemp(tmppath)) == -1) |
err(1, "mkstemp"); |
err(1, "mkstemp"); |
|
wantcleanup = 1; |
|
atexit(cleanup); |
if ((fp = fdopen(fd, "w+")) == NULL) { |
if ((fp = fdopen(fd, "w+")) == NULL) { |
warn("fdopen"); |
err(1, "fdopen"); |
goto cleanup; |
|
} |
} |
|
|
if (init() == -1) |
init(); |
goto cleanup; |
|
|
|
pr_form = getenv("PR_FORM"); |
pr_form = getenv("PR_FORM"); |
if (pr_form) { |
if (pr_form) { |
|
|
template(fp); |
template(fp); |
|
|
if (fflush(fp) == EOF || fstat(fd, &sb) == -1 || fclose(fp) == EOF) { |
if (fflush(fp) == EOF || fstat(fd, &sb) == -1 || fclose(fp) == EOF) { |
warn("error creating template"); |
err(1, "error creating template"); |
goto cleanup; |
|
} |
} |
mtime = sb.st_mtime; |
mtime = sb.st_mtime; |
|
|
|
|
editor = "vi"; |
editor = "vi"; |
switch (fork()) { |
switch (fork()) { |
case -1: |
case -1: |
warn("fork"); |
err(1, "fork"); |
goto cleanup; |
|
case 0: |
case 0: |
|
wantcleanup = 0; |
if (asprintf(&argp[2], "%s %s", editor, tmppath) == -1) |
if (asprintf(&argp[2], "%s %s", editor, tmppath) == -1) |
err(1, "asprintf"); |
err(1, "asprintf"); |
execv(_PATH_BSHELL, argp); |
execv(_PATH_BSHELL, argp); |
|
|
} |
} |
|
|
if (stat(tmppath, &sb) == -1) { |
if (stat(tmppath, &sb) == -1) { |
warn("stat"); |
err(1, "stat"); |
goto cleanup; |
|
} |
} |
if (mtime == sb.st_mtime) { |
if (mtime == sb.st_mtime) { |
warnx("report unchanged, nothing sent"); |
errx(1, "report unchanged, nothing sent"); |
goto cleanup; |
|
} |
} |
|
|
prompt: |
prompt: |
|
|
switch (c) { |
switch (c) { |
case 'a': |
case 'a': |
case EOF: |
case EOF: |
warnx("unsent report in %s", tmppath); |
wantcleanup = 0; |
goto quit; |
errx(1, "unsent report in %s", tmppath); |
case 'e': |
case 'e': |
goto edit; |
goto edit; |
case 's': |
case 's': |
|
|
} |
} |
|
|
ret = 0; |
ret = 0; |
|
quit: |
cleanup: |
|
if (tmppath && unlink(tmppath) == -1) |
|
warn("unlink"); |
|
|
|
quit: |
|
return (ret); |
return (ret); |
} |
} |
|
|
|
|
int |
int |
prompt(void) |
prompt(void) |
{ |
{ |
|
|
return (0); |
return (0); |
} |
} |
|
|
int |
void |
init(void) |
init(void) |
{ |
{ |
size_t len; |
size_t len; |
int sysname[2]; |
int sysname[2]; |
|
|
if ((pw = getpwuid(getuid())) == NULL) { |
if ((pw = getpwuid(getuid())) == NULL) { |
warn("getpwuid"); |
err(1, "getpwuid"); |
return (-1); |
|
} |
} |
|
|
/* Get full name. */ |
/* Get full name. */ |
len = strcspn(pw->pw_gecos, ","); |
len = strcspn(pw->pw_gecos, ","); |
if ((fullname = malloc(len + 1)) == NULL) { |
if ((fullname = malloc(len + 1)) == NULL) { |
warn("malloc"); |
err(1, "malloc"); |
return (-1); |
|
} |
} |
memcpy(fullname, pw->pw_gecos, len); |
memcpy(fullname, pw->pw_gecos, len); |
fullname[len] = '\0'; |
fullname[len] = '\0'; |
|
|
sysname[1] = KERN_OSTYPE; |
sysname[1] = KERN_OSTYPE; |
len = sizeof(os) - 1; |
len = sizeof(os) - 1; |
if (sysctl(sysname, 2, &os, &len, NULL, 0) == -1) { |
if (sysctl(sysname, 2, &os, &len, NULL, 0) == -1) { |
warn("sysctl"); |
err(1, "sysctl"); |
return (-1); |
|
} |
} |
|
|
sysname[0] = CTL_KERN; |
sysname[0] = CTL_KERN; |
sysname[1] = KERN_OSRELEASE; |
sysname[1] = KERN_OSRELEASE; |
len = sizeof(rel) - 1; |
len = sizeof(rel) - 1; |
if (sysctl(sysname, 2, &rel, &len, NULL, 0) == -1) { |
if (sysctl(sysname, 2, &rel, &len, NULL, 0) == -1) { |
warn("sysctl"); |
err(1, "sysctl"); |
return (-1); |
|
} |
} |
|
|
sysname[0] = CTL_HW; |
sysname[0] = CTL_HW; |
sysname[1] = HW_MACHINE; |
sysname[1] = HW_MACHINE; |
len = sizeof(mach) - 1; |
len = sizeof(mach) - 1; |
if (sysctl(sysname, 2, &mach, &len, NULL, 0) == -1) { |
if (sysctl(sysname, 2, &mach, &len, NULL, 0) == -1) { |
warn("sysctl"); |
err(1, "sysctl"); |
return (-1); |
|
} |
} |
|
|
return (0); |
|
} |
} |
|
|
int |
int |