}
}
+char *get_core_detail_filename(char *filename)
+{
+ char *pid, *c, *s;
+ char *detail_filename;
+
+ if (!(s = strstr(filename, ".")))
+ return NULL;
+
+ pid = strdup(++s);
+ if (!(c = strstr(pid, "."))) {
+ free(pid);
+ return NULL;
+ }
+
+ *c = '\0';
+
+ if ((asprintf(&detail_filename, "%s%s.txt", core_folder, pid)) < 0) {
+ free(pid);
+ return NULL;
+ }
+
+ free(pid);
+ return detail_filename;
+}
+
+char *remove_directories(char *fullname)
+{
+ char *dfile = NULL, *c = NULL, *d = NULL;
+ char delim[] = "/";
+
+ dfile = strdup(fullname);
+ if (!dfile)
+ return NULL;
+
+ c = strtok(dfile, delim);
+ while(c) {
+ d = c;
+ c = strtok(NULL, delim);
+ }
+ d = strdup(d);
+ free(dfile);
+
+ return d;
+}
+
void process_corefile(char *filename)
{
struct oops *oops;
- char newfile[8192];
+ char newfile[8192], *fn = NULL;
oops = extract_core(filename);
return;
}
- /* if this oops hasn't been processed before need to write details out and rename */
- if (!strstr(filename, ".processed")) {
- char *dfile = NULL, *c = NULL, *d = NULL;
- char delim[] = "/";
-
- dfile = strdup(filename);
- if (!dfile)
- return;
+ if (!(fn = remove_directories(filename))) {
+ FREE_OOPS(oops);
+ return;
+ }
- c = strtok(dfile, delim);
- while(c) {
- d = c;
- c = strtok(NULL, delim);
- }
+ /* if this oops hasn't been processed before need to write details out and rename */
+ if (!strstr(fn, ".processed")) {
fprintf(stderr, "---[start of coredump]---\n%s\n---[end of coredump]---\n", oops->text);
dbus_say_found(oops);
+ if (!mkdir(core_folder, S_IRWXU | S_IRWXG | S_IRWXO) && errno != EEXIST) {
+ free(fn);
+ FREE_OOPS(oops);
+ return;
+ }
/* try to write coredump text details to text file */
write_core_detail_file(filename, oops->text);
- if (!mkdir(core_folder, S_IRWXU | S_IRWXG | S_IRWXO) && errno != EEXIST)
- return;
- sprintf(newfile,"%s%s.processed", core_folder, d);
+ sprintf(newfile,"%s%s.processed", core_folder, fn);
rename(filename, newfile);
- free(dfile);
- free(oops->filename);
- oops->filename = strdup(newfile);
+
} else {
/* backtrace queued only if files have been processed
to avoid putting a new coredump in twice */
+ oops->detail_filename = get_core_detail_filename(fn);
queue_backtrace(oops);
}
- free(oops->application);
- free(oops->text);
- free(oops->filename);
- free(oops);
+ free(fn);
+ FREE_OOPS(oops);
}
if (opted_in >= 2)
submit_queue();
else if (opted_in >= 1)
- ask_permission();
+ ask_permission(core_folder);
return 1;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
-void dbus_ask_permission(char * detail_file_name)
+void dbus_ask_permission(char * detail_folder)
{
DBusMessage *message;
if (!bus)
return;
message = dbus_message_new_signal("/org/corewatcher/submit/permission",
"org.corewatcher.submit.permission", "ask");
- if (detail_file_name) {
+ if (detail_folder) {
dbus_message_append_args(message,
- DBUS_TYPE_STRING, &detail_file_name,
+ DBUS_TYPE_STRING, &detail_folder,
DBUS_TYPE_INVALID);
}
dbus_connection_send(bus, message, NULL);
#define MAX_URLS 9
+#define FREE_OOPS(oops) \
+ do { \
+ free(oops->application); \
+ free(oops->text); \
+ free(oops->filename); \
+ free(oops->detail_filename); \
+ free(oops); \
+ } while(0)
+
struct oops {
struct oops *next;
char *application;
char *text;
char *filename;
+ char *detail_filename;
unsigned int checksum;
};
extern int scan_dmesg(void * unused);
extern void read_config_file(char *filename);
-extern void ask_permission(void);
-extern void dbus_ask_permission(char * detail_file_name);
+
+extern void ask_permission(char *detail_folder);
+extern void dbus_ask_permission(char *detail_folder);
extern void dbus_say_thanks(char *url);
extern void dbus_say_found(struct oops *oops);
static int newoops;
static int unsubmittedoops;
-/* For communicating details to the applet, we write the
- * details in a file, and provide the filename to the applet
- */
-static char *detail_filename;
-
-
static unsigned int checksum(char *ptr)
{
unsigned int temp = 0;
new->application = strdup(oops->application);
new->text = strdup(oops->text);
new->filename = strdup(oops->filename);
+ new->detail_filename = strdup(oops->detail_filename);
queued_backtraces = new;
unsubmittedoops = 1;
}
-
-void write_detail_file(void)
-{
- int temp_fileno;
- FILE *tmpf;
- struct oops *oops;
- int count = 0;
-
- detail_filename = strdup("/tmp/corewatcher.XXXXXX");
- temp_fileno = mkstemp(detail_filename);
- if (temp_fileno < 0) {
- free(detail_filename);
- detail_filename = NULL;
- return;
- }
- /* regular user must be able to read this detail file to be
- * useful; there is nothing worth doing if fchmod fails.
- */
- fchmod(temp_fileno, 0644);
- tmpf = fdopen(temp_fileno, "w");
- oops = queued_backtraces;
- while (oops) {
- count++; /* Users are not programmers, start at 1 */
- fprintf(tmpf, "Application failure message %d:\n", count);
- fprintf(tmpf, "%s", oops->text);
- fprintf(tmpf, "\n\n");
- oops = oops->next;
- }
- fclose(tmpf);
- close(temp_fileno);
-}
-
-void unlink_detail_file(void)
-{
- if (detail_filename) {
- if (do_unlink)
- unlink(detail_filename);
- free(detail_filename);
- }
-}
-
-
static void print_queue(void)
{
struct oops *oops, *next;
while (oops) {
fprintf(stderr, "+ Submit text is:\n---[start of oops]---\n%s\n---[end of oops]---\n", oops->text);
next = oops->next;
- free(oops->application);
- free(oops->text);
- free(oops->filename);
- free(oops);
+ FREE_OOPS(oops);
oops = next;
count++;
}
sprintf(newfile,"%s.submitted", oldfile);
- if (do_unlink)
+ if (do_unlink) {
+ unlink(oops->detail_filename);
unlink(oops->filename);
+ }
else
rename(oops->filename, newfile);
* the program won't do any useful work anymore going forward.
*/
if (submitted >= MAX_CHECKSUMS-1) {
- unlink_detail_file();
exit(EXIT_SUCCESS);
}
}
oops = queue;
while (oops) {
next = oops->next;
- free(oops->application);
- free(oops->text);
- free(oops->filename);
- free(oops);
+ FREE_OOPS(oops);
oops = next;
}
oops = queue;
while (oops) {
next = oops->next;
- free(oops->application);
- free(oops->text);
- free(oops->filename);
- free(oops);
+ FREE_OOPS(oops);
oops = next;
}
write_logfile(0, "Unknown");
}
-void ask_permission(void)
+void ask_permission(char *detail_folder)
{
if (!newoops && !pinged && !unsubmittedoops)
return;
newoops = 0;
unsubmittedoops = 0;
if (queued_backtraces) {
- write_detail_file();
- dbus_ask_permission(detail_filename);
+ dbus_ask_permission(detail_folder);
}
}