/*
Copyright (C) 2013 RedHat inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <sys/un.h>
#include "libabrt.h"
void notify_new_path(const char *path)
{
/* Ignore results and don't wait for response -> NULL */
notify_new_path_with_response(path, NULL);
}
int notify_new_path_with_response(const char *path, char **message)
{
int retval;
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0)
{
retval = -errno;
perror_msg("socket(AF_UNIX)");
return retval;
}
struct sockaddr_un sunx;
memset(&sunx, 0, sizeof(sunx));
sunx.sun_family = AF_UNIX;
strcpy(sunx.sun_path, VAR_RUN"/abrt/abrt.socket");
if (connect(fd, (struct sockaddr *)&sunx, sizeof(sunx)))
{
retval = -errno;
perror_msg("connect('%s')", sunx.sun_path);
close(fd);
return retval;
}
full_write_str(fd, "POST /creation_notification HTTP/1.1\r\n\r\n");
full_write_str(fd, path);
/*
* This sends FIN packet. Without it, close() may result in RST instead.
* Not really needed on AF_UNIX, just a bit of TCP-induced paranoia
* aka "good practice".
*/
shutdown(fd, SHUT_WR);
if (message == NULL)
{
close(fd);
return 0;
}
*message = xmalloc_read(fd, NULL);
if (*message == NULL)
{
log_info("abrtd response could not be received");
return -EBADMSG;
}
close(fd);
unsigned code = 0;
if (sscanf(*message, "HTTP/1.1 %u ", &code) != 1)
{
log_info("abrtd response does not contain HTTP code");
return -EBADMSG;
}
/* Verify possible casting to int. */
if (code > INT_MAX)
{
log_info("abrtd response HTTP code is out of range");
return -EBADMSG;
}
char *data = strchr(*message, '\n');
if (data == NULL)
{
log_info("abrtd response is missing the first new line");
return -EBADMSG;
}
data = strchr(data + 1, '\n');
if (data == NULL)
{
log_info("abrtd response is missing the second new line");
return -EBADMSG;
}
memmove(*message, data + 1, strlen(data));
/* If code is greater than INT_MAX, -EBADMSG is returned. */
return (int)code;
}