mirror of
https://github.com/clearlinux/clr-debug-info.git
synced 2026-09-05 13:21:33 +00:00
Apply clang-format to codebase (switching to spaces for maintainence)
Signed-off-by: Ikey Doherty <michael.i.doherty@intel.com>
This commit is contained in:
+67
-66
@@ -7,12 +7,12 @@
|
||||
* 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, version 2 or later of the License.
|
||||
*
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
@@ -23,16 +23,16 @@
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* 0.75 seconds timeout */
|
||||
#define TIMEOUT 750000
|
||||
@@ -45,71 +45,72 @@ time_t deadtime;
|
||||
|
||||
void try_to_get(const char *path, int pid, time_t timestamp)
|
||||
{
|
||||
int sockfd;
|
||||
struct sockaddr_un sun;
|
||||
int ret;
|
||||
socklen_t len;
|
||||
char *command;
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
struct ucred cred;
|
||||
int shorttime = 0;
|
||||
|
||||
// printf("Trying to aquire %s\n", path);
|
||||
|
||||
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sockfd < 0)
|
||||
return;
|
||||
|
||||
sun.sun_family = AF_UNIX;
|
||||
strcpy(sun.sun_path, ":clr-debug-info");
|
||||
sun.sun_path[0] = 0; /* anonymous unix socket */
|
||||
int sockfd;
|
||||
struct sockaddr_un sun;
|
||||
int ret;
|
||||
socklen_t len;
|
||||
char *command;
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
struct ucred cred;
|
||||
int shorttime = 0;
|
||||
|
||||
ret = connect(sockfd, (struct sockaddr *)&sun, offsetof(struct sockaddr_un, sun_path) + strlen(":clr-debug-info") + 1);
|
||||
if (ret < 0) {
|
||||
printf("Cannot connect %s\n", strerror(errno));
|
||||
close(sockfd);
|
||||
return;
|
||||
}
|
||||
// printf("Trying to aquire %s\n", path);
|
||||
|
||||
len = sizeof(cred);
|
||||
memset(&cred, 0, sizeof(cred));
|
||||
ret = getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cred, &len);
|
||||
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sockfd < 0)
|
||||
return;
|
||||
|
||||
if (ret == 0 && cred.pid == pid) {
|
||||
printf("Recursion\n");
|
||||
close(sockfd);
|
||||
}
|
||||
sun.sun_family = AF_UNIX;
|
||||
strcpy(sun.sun_path, ":clr-debug-info");
|
||||
sun.sun_path[0] = 0; /* anonymous unix socket */
|
||||
|
||||
command = NULL;
|
||||
if (asprintf(&command, "%llu:%s:%s", (unsigned long long)timestamp, prefix, path) < 0) {
|
||||
close(sockfd);
|
||||
return;
|
||||
}
|
||||
write(sockfd, command, strlen(command )+1);
|
||||
ret = connect(sockfd,
|
||||
(struct sockaddr *)&sun,
|
||||
offsetof(struct sockaddr_un, sun_path) + strlen(":clr-debug-info") + 1);
|
||||
if (ret < 0) {
|
||||
printf("Cannot connect %s\n", strerror(errno));
|
||||
close(sockfd);
|
||||
return;
|
||||
}
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(sockfd, &rfds);
|
||||
len = sizeof(cred);
|
||||
memset(&cred, 0, sizeof(cred));
|
||||
ret = getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cred, &len);
|
||||
|
||||
/* Wait up to 0.5 seconds. */
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = TIMEOUT;
|
||||
|
||||
/* if we had a timeout recently, must go quicker to avoid sequential delays */
|
||||
if (deadtime > time(NULL)) {
|
||||
tv.tv_usec = TIMEOUT2;
|
||||
shorttime = 1;
|
||||
}
|
||||
if (ret == 0 && cred.pid == pid) {
|
||||
printf("Recursion\n");
|
||||
close(sockfd);
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
command = NULL;
|
||||
if (asprintf(&command, "%llu:%s:%s", (unsigned long long)timestamp, prefix, path) < 0) {
|
||||
close(sockfd);
|
||||
return;
|
||||
}
|
||||
write(sockfd, command, strlen(command) + 1);
|
||||
|
||||
if (!timestamp)
|
||||
ret = select(sockfd+1, &rfds, NULL, &rfds, &tv);
|
||||
if (ret == 0 && !shorttime) {
|
||||
printf("timeout for %s\n", path);
|
||||
deadtime = time(NULL) + 4;
|
||||
}
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(sockfd, &rfds);
|
||||
|
||||
close(sockfd);
|
||||
/* Wait up to 0.5 seconds. */
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = TIMEOUT;
|
||||
|
||||
/* if we had a timeout recently, must go quicker to avoid sequential delays */
|
||||
if (deadtime > time(NULL)) {
|
||||
tv.tv_usec = TIMEOUT2;
|
||||
shorttime = 1;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
if (!timestamp)
|
||||
ret = select(sockfd + 1, &rfds, NULL, &rfds, &tv);
|
||||
if (ret == 0 && !shorttime) {
|
||||
printf("timeout for %s\n", path);
|
||||
deadtime = time(NULL) + 4;
|
||||
}
|
||||
|
||||
close(sockfd);
|
||||
}
|
||||
|
||||
+404
-414
File diff suppressed because it is too large
Load Diff
+150
-139
@@ -9,12 +9,12 @@
|
||||
* 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, version 2 or later of the License.
|
||||
*
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
@@ -24,194 +24,205 @@
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/*
|
||||
/*
|
||||
|
||||
this program takes a directory /var/www/html/debuginfo.raw,
|
||||
in which all debuginfo rpms have previously been rpm2cpio'd, and
|
||||
creates the content for /var/www/html/debuginfo
|
||||
which contains tar'd up/compressed versions of all the files.
|
||||
As part of this symlinks will be resolved server side
|
||||
As part of this symlinks will be resolved server side
|
||||
as much as possible.
|
||||
|
||||
*/
|
||||
|
||||
static void unsymlink(char *filename)
|
||||
{
|
||||
char *target;
|
||||
char *target;
|
||||
|
||||
target = canonicalize_file_name(filename);
|
||||
// sleep(1);
|
||||
// printf("Symlink %s points to %s\n", filename, target);
|
||||
unlink(filename);
|
||||
link(target, filename);
|
||||
target = canonicalize_file_name(filename);
|
||||
// sleep(1);
|
||||
// printf("Symlink %s points to %s\n", filename, target);
|
||||
unlink(filename);
|
||||
link(target, filename);
|
||||
}
|
||||
|
||||
|
||||
static void wait_for_loadavg(void)
|
||||
{
|
||||
FILE *file;
|
||||
char line[4096];
|
||||
while (1) {
|
||||
double d;
|
||||
file = fopen("/proc/loadavg", "r");
|
||||
if (!file)
|
||||
return;
|
||||
line[0] = 0;
|
||||
fgets(line, 4096, file);
|
||||
fclose(file);
|
||||
d = strtod(line, NULL);
|
||||
if (d < 50)
|
||||
return;
|
||||
sleep(5);
|
||||
|
||||
}
|
||||
FILE *file;
|
||||
char line[4096];
|
||||
while (1) {
|
||||
double d;
|
||||
file = fopen("/proc/loadavg", "r");
|
||||
if (!file)
|
||||
return;
|
||||
line[0] = 0;
|
||||
fgets(line, 4096, file);
|
||||
fclose(file);
|
||||
d = strtod(line, NULL);
|
||||
if (d < 50)
|
||||
return;
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
int tarcount;
|
||||
|
||||
static void do_one_file(char *base1, char *base2, char *path, int isdir)
|
||||
{
|
||||
char *fullpath1 = NULL, *fullpath2 = NULL, *dir, *dir2;
|
||||
struct stat buf1, buf2;
|
||||
int ret;
|
||||
char *fullpath1 = NULL, *fullpath2 = NULL, *dir, *dir2;
|
||||
struct stat buf1, buf2;
|
||||
int ret;
|
||||
|
||||
if (asprintf(&fullpath1, "%s%s", base1, path) < 0)
|
||||
return;
|
||||
if (asprintf(&fullpath2, "%s%s.tar", base2, path) < 0) {
|
||||
free(fullpath1);
|
||||
return;
|
||||
}
|
||||
if (asprintf(&fullpath1, "%s%s", base1, path) < 0)
|
||||
return;
|
||||
if (asprintf(&fullpath2, "%s%s.tar", base2, path) < 0) {
|
||||
free(fullpath1);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = lstat(fullpath1, &buf1);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = lstat(fullpath1, &buf1);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (S_ISLNK(buf1.st_mode)) {
|
||||
// printf("%s is a symlink\n", fullpath1);
|
||||
ret = stat(fullpath1, &buf2);
|
||||
if (!ret)
|
||||
unsymlink(fullpath1);
|
||||
ret = lstat(fullpath1, &buf1);
|
||||
}
|
||||
if (S_ISLNK(buf1.st_mode)) {
|
||||
// printf("%s is a symlink\n", fullpath1);
|
||||
ret = stat(fullpath1, &buf2);
|
||||
if (!ret)
|
||||
unsymlink(fullpath1);
|
||||
ret = lstat(fullpath1, &buf1);
|
||||
}
|
||||
|
||||
ret = lstat(fullpath2, &buf2);
|
||||
if (ret || buf1.st_mtime > buf2.st_mtime) {
|
||||
char *command = NULL;
|
||||
unlink(fullpath2);
|
||||
ret = lstat(fullpath2, &buf2);
|
||||
if (ret || buf1.st_mtime > buf2.st_mtime) {
|
||||
char *command = NULL;
|
||||
unlink(fullpath2);
|
||||
|
||||
dir = strdup(fullpath2);
|
||||
dir = strdup(fullpath2);
|
||||
|
||||
dir2 = dirname(dir);
|
||||
dir2 = dirname(dir);
|
||||
|
||||
if (asprintf(&command, "mkdir -p %s", dir2) >= 0) {
|
||||
// printf("Running -%s-\n", command);
|
||||
system(command);
|
||||
free(command);
|
||||
}
|
||||
if (asprintf(&command, "mkdir -p %s", dir2) >= 0) {
|
||||
// printf("Running -%s-\n", command);
|
||||
system(command);
|
||||
free(command);
|
||||
}
|
||||
|
||||
free(dir);
|
||||
chdir(base1);
|
||||
if (!isdir && asprintf(&command, "tar --no-recursion -C %s -Jcf %s %s &", base1, fullpath2, path) >= 0) {
|
||||
// printf("Running -%s-\n", command);
|
||||
printf("Processing %s\n", fullpath2);
|
||||
tarcount++;
|
||||
if (tarcount > 50) {
|
||||
wait_for_loadavg();
|
||||
tarcount = 0;
|
||||
}
|
||||
system(command);
|
||||
free(command);
|
||||
}
|
||||
free(dir);
|
||||
chdir(base1);
|
||||
if (!isdir &&
|
||||
asprintf(&command,
|
||||
"tar --no-recursion -C %s -Jcf %s %s &",
|
||||
base1,
|
||||
fullpath2,
|
||||
path) >= 0) {
|
||||
// printf("Running -%s-\n", command);
|
||||
printf("Processing %s\n", fullpath2);
|
||||
tarcount++;
|
||||
if (tarcount > 50) {
|
||||
wait_for_loadavg();
|
||||
tarcount = 0;
|
||||
}
|
||||
system(command);
|
||||
free(command);
|
||||
}
|
||||
|
||||
if (isdir && asprintf(&command, "tar --no-recursion -C %s -Jcf %s `find %s -type d` `find %s -maxdepth 1 -type l` &", base1, fullpath2, path, path) >= 0) {
|
||||
// printf("Running -%s-\n", command);
|
||||
printf("Processing %s\n", fullpath2);
|
||||
tarcount++;
|
||||
if (tarcount > 50) {
|
||||
wait_for_loadavg();
|
||||
tarcount = 0;
|
||||
}
|
||||
system(command);
|
||||
free(command);
|
||||
}
|
||||
|
||||
}
|
||||
if (isdir &&
|
||||
asprintf(&command,
|
||||
"tar --no-recursion -C %s -Jcf %s `find %s -type d` `find %s "
|
||||
"-maxdepth 1 -type l` &",
|
||||
base1,
|
||||
fullpath2,
|
||||
path,
|
||||
path) >= 0) {
|
||||
// printf("Running -%s-\n", command);
|
||||
printf("Processing %s\n", fullpath2);
|
||||
tarcount++;
|
||||
if (tarcount > 50) {
|
||||
wait_for_loadavg();
|
||||
tarcount = 0;
|
||||
}
|
||||
system(command);
|
||||
free(command);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
free(fullpath1);
|
||||
free(fullpath2);
|
||||
free(fullpath1);
|
||||
free(fullpath2);
|
||||
}
|
||||
|
||||
|
||||
static void recurse_dir(char *base1, char *base2, char *path)
|
||||
{
|
||||
DIR *dir;
|
||||
char *fullpath1, *fullpath2, *newpath;
|
||||
struct dirent *entry;
|
||||
DIR *dir;
|
||||
char *fullpath1, *fullpath2, *newpath;
|
||||
struct dirent *entry;
|
||||
|
||||
fullpath1 = NULL;
|
||||
fullpath2 = NULL;
|
||||
fullpath1 = NULL;
|
||||
fullpath2 = NULL;
|
||||
|
||||
if (asprintf(&fullpath1, "%s%s", base1, path) < 0)
|
||||
return;
|
||||
|
||||
if (asprintf(&fullpath1, "%s%s", base1, path) < 0)
|
||||
return;
|
||||
dir = opendir(fullpath1);
|
||||
|
||||
dir = opendir(fullpath1);
|
||||
if (!dir) {
|
||||
free(fullpath1);
|
||||
return;
|
||||
}
|
||||
while (1) {
|
||||
entry = readdir(dir);
|
||||
if (!entry)
|
||||
break;
|
||||
if (strcmp(entry->d_name, ".") == 0)
|
||||
continue;
|
||||
if (strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
if (!dir) {
|
||||
free(fullpath1);
|
||||
return;
|
||||
}
|
||||
while (1) {
|
||||
entry = readdir(dir);
|
||||
if (!entry)
|
||||
break;
|
||||
if (strcmp(entry->d_name, ".") == 0)
|
||||
continue;
|
||||
if (strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
newpath = NULL;
|
||||
fullpath2 = NULL;
|
||||
asprintf(&fullpath2, "%s/%s", fullpath1, entry->d_name);
|
||||
if (asprintf(&newpath, "%s/%s", path, entry->d_name) >= 0) {
|
||||
struct stat sb;
|
||||
stat(fullpath2, &sb);
|
||||
|
||||
if (entry->d_type == DT_DIR || S_ISDIR(sb.st_mode)) {
|
||||
do_one_file(base1, base2, newpath, 1);
|
||||
recurse_dir(base1, base2, newpath);
|
||||
} else {
|
||||
do_one_file(base1, base2, newpath, 0);
|
||||
}
|
||||
free(newpath);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
free(fullpath1);
|
||||
newpath = NULL;
|
||||
fullpath2 = NULL;
|
||||
asprintf(&fullpath2, "%s/%s", fullpath1, entry->d_name);
|
||||
if (asprintf(&newpath, "%s/%s", path, entry->d_name) >= 0) {
|
||||
struct stat sb;
|
||||
stat(fullpath2, &sb);
|
||||
|
||||
if (entry->d_type == DT_DIR || S_ISDIR(sb.st_mode)) {
|
||||
do_one_file(base1, base2, newpath, 1);
|
||||
recurse_dir(base1, base2, newpath);
|
||||
} else {
|
||||
do_one_file(base1, base2, newpath, 0);
|
||||
}
|
||||
free(newpath);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
free(fullpath1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 0)
|
||||
(void)argv;
|
||||
recurse_dir("/var/www/html/debuginfo.raw/usr/lib/debug/", "/var/www/html/debuginfo/lib/", ".");
|
||||
recurse_dir("/var/www/html/debuginfo.raw/usr/src/debug/", "/var/www/html/debuginfo/src/", ".");
|
||||
if (argc < 0)
|
||||
(void)argv;
|
||||
recurse_dir("/var/www/html/debuginfo.raw/usr/lib/debug/",
|
||||
"/var/www/html/debuginfo/lib/",
|
||||
".");
|
||||
recurse_dir("/var/www/html/debuginfo.raw/usr/src/debug/",
|
||||
"/var/www/html/debuginfo/src/",
|
||||
".");
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
+215
-215
@@ -9,12 +9,12 @@
|
||||
* 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, version 3 or later of the License.
|
||||
*
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
@@ -24,288 +24,288 @@
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <glib.h>
|
||||
|
||||
static GMutex dupes_mutex;
|
||||
|
||||
char *urls[2] = {"https://debuginfo.clearlinux.org/debuginfo/", "https://debuginfo.clearlinux.org/debuginfo/" };
|
||||
char *urls[2] = { "https://debuginfo.clearlinux.org/debuginfo/",
|
||||
"https://debuginfo.clearlinux.org/debuginfo/" };
|
||||
int urlcounter = 1;
|
||||
|
||||
|
||||
static GHashTable *hash;
|
||||
|
||||
static int avoid_dupes(const char *url)
|
||||
{
|
||||
int retval = 0;
|
||||
void *value;
|
||||
g_mutex_lock(&dupes_mutex);
|
||||
int retval = 0;
|
||||
void *value;
|
||||
g_mutex_lock(&dupes_mutex);
|
||||
|
||||
if (hash == NULL)
|
||||
hash = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
if (hash == NULL)
|
||||
hash = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
|
||||
if (g_hash_table_lookup_extended(hash, url, NULL, &value)) {
|
||||
unsigned long tm;
|
||||
tm = (unsigned long)value;
|
||||
if (time(NULL) - tm < 600) {
|
||||
retval = 1;
|
||||
}
|
||||
} else {
|
||||
unsigned long tm;
|
||||
tm = time(NULL);
|
||||
void *data = (void *)(unsigned long)tm;
|
||||
g_hash_table_replace(hash, strdup(url), data);
|
||||
}
|
||||
if (g_hash_table_lookup_extended(hash, url, NULL, &value)) {
|
||||
unsigned long tm;
|
||||
tm = (unsigned long)value;
|
||||
if (time(NULL) - tm < 600) {
|
||||
retval = 1;
|
||||
}
|
||||
} else {
|
||||
unsigned long tm;
|
||||
tm = time(NULL);
|
||||
void *data = (void *)(unsigned long)tm;
|
||||
g_hash_table_replace(hash, strdup(url), data);
|
||||
}
|
||||
|
||||
g_mutex_unlock(&dupes_mutex);
|
||||
return retval;
|
||||
g_mutex_unlock(&dupes_mutex);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int curl_get_file(const char *url, const char *prefix, time_t timestamp)
|
||||
{
|
||||
CURLcode code;
|
||||
CURLcode code;
|
||||
long ret;
|
||||
int fd;
|
||||
char filename[PATH_MAX];
|
||||
CURL *curl = NULL;
|
||||
FILE *file;
|
||||
struct stat statbuf;
|
||||
int fd;
|
||||
char filename[PATH_MAX];
|
||||
CURL *curl = NULL;
|
||||
FILE *file;
|
||||
struct stat statbuf;
|
||||
|
||||
if (avoid_dupes(url))
|
||||
return 300;
|
||||
if (avoid_dupes(url))
|
||||
return 300;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if (curl == NULL)
|
||||
return 301;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if (curl == NULL)
|
||||
return 301;
|
||||
strcpy(filename, "/tmp/clr-debug-info-XXXXXX");
|
||||
|
||||
fd = mkstemp(filename);
|
||||
if (fd < 0) {
|
||||
curl_easy_cleanup(curl);
|
||||
return 500;
|
||||
}
|
||||
|
||||
strcpy(filename, "/tmp/clr-debug-info-XXXXXX");
|
||||
|
||||
fd = mkstemp(filename);
|
||||
if (fd < 0) {
|
||||
curl_easy_cleanup(curl);
|
||||
return 500;
|
||||
}
|
||||
file = fdopen(fd, "w");
|
||||
|
||||
file = fdopen(fd, "w");
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
|
||||
if (timestamp) {
|
||||
curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEVALUE, timestamp);
|
||||
}
|
||||
|
||||
if (timestamp) {
|
||||
curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEVALUE, timestamp);
|
||||
}
|
||||
code = curl_easy_perform(curl);
|
||||
|
||||
code = curl_easy_perform(curl);
|
||||
/* can't trust the file if we get an error back */
|
||||
if (code != 0)
|
||||
unlink(filename);
|
||||
|
||||
/* can't trust the file if we get an error back */
|
||||
if (code != 0)
|
||||
unlink(filename);
|
||||
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &ret);
|
||||
fflush(file);
|
||||
// printf("HTTP return code is %i\n", ret);
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &ret);
|
||||
fflush(file);
|
||||
// printf("HTTP return code is %i\n", ret);
|
||||
|
||||
/* HTTP 304 is returned if (a) the cached debuginfo has the same
|
||||
* timestamp or is newer than that on the server and (b) we haven't
|
||||
* already added the URL to the hash table. So, the first crash for a
|
||||
* boot may result in a 304 if the debuginfo had been downloaded in a
|
||||
* previous boot.
|
||||
*/
|
||||
if (ret != 200 && ret != 404 && ret != 304)
|
||||
urlcounter++;
|
||||
/* HTTP 304 is returned if (a) the cached debuginfo has the same
|
||||
* timestamp or is newer than that on the server and (b) we haven't
|
||||
* already added the URL to the hash table. So, the first crash for a
|
||||
* boot may result in a 304 if the debuginfo had been downloaded in a
|
||||
* previous boot.
|
||||
*/
|
||||
if (ret != 200 && ret != 404 && ret != 304)
|
||||
urlcounter++;
|
||||
|
||||
if (ret == 200) {
|
||||
char *command = NULL;
|
||||
// printf("Filename is %s\n", filename);
|
||||
if (ret == 200) {
|
||||
char *command = NULL;
|
||||
// printf("Filename is %s\n", filename);
|
||||
|
||||
memset(&statbuf, 0, sizeof(statbuf));
|
||||
stat(filename, &statbuf);
|
||||
if (statbuf.st_size > 0 && asprintf(&command, "tar -C /var/cache/debuginfo/%s --no-same-owner -xf %s", prefix, filename) >= 0) {
|
||||
system(command);
|
||||
free(command);
|
||||
}
|
||||
}
|
||||
unlink(filename);
|
||||
curl_easy_cleanup(curl);
|
||||
fclose(file);
|
||||
return ret;
|
||||
memset(&statbuf, 0, sizeof(statbuf));
|
||||
stat(filename, &statbuf);
|
||||
if (statbuf.st_size > 0 &&
|
||||
asprintf(&command,
|
||||
"tar -C /var/cache/debuginfo/%s --no-same-owner -xf %s",
|
||||
prefix,
|
||||
filename) >= 0) {
|
||||
system(command);
|
||||
free(command);
|
||||
}
|
||||
}
|
||||
unlink(filename);
|
||||
curl_easy_cleanup(curl);
|
||||
fclose(file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
double timedelta(struct timeval before, struct timeval after)
|
||||
{
|
||||
double d;
|
||||
d = 1.0 * (after.tv_sec - before.tv_sec) + (1.0 * after.tv_usec - before.tv_usec)/1000000.0;
|
||||
return d;
|
||||
double d;
|
||||
d = 1.0 * (after.tv_sec - before.tv_sec) +
|
||||
(1.0 * after.tv_usec - before.tv_usec) / 1000000.0;
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void *server_thread(void *arg)
|
||||
{
|
||||
int fd;
|
||||
char buf[PATH_MAX+8];
|
||||
int ret;
|
||||
char *prefix, *path, *url, *c;
|
||||
time_t timestamp;
|
||||
struct timeval before, after;
|
||||
int fd;
|
||||
char buf[PATH_MAX + 8];
|
||||
int ret;
|
||||
char *prefix, *path, *url, *c;
|
||||
time_t timestamp;
|
||||
struct timeval before, after;
|
||||
|
||||
fd = (unsigned long)arg;
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
gettimeofday(&before, NULL);
|
||||
fd = (unsigned long)arg;
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
gettimeofday(&before, NULL);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
ret = read(fd, buf, PATH_MAX+8);
|
||||
if (ret < 0) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
prefix = buf;
|
||||
c = strchr(buf, ':');
|
||||
if (!c) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
*c = 0;
|
||||
timestamp = strtoull(buf, NULL, 10);
|
||||
c++;
|
||||
prefix = c;
|
||||
path = strchr(c, ':');
|
||||
if (!path) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
*path = 0;
|
||||
path++;
|
||||
memset(buf, 0, sizeof(buf));
|
||||
ret = read(fd, buf, PATH_MAX + 8);
|
||||
if (ret < 0) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
prefix = buf;
|
||||
c = strchr(buf, ':');
|
||||
if (!c) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
*c = 0;
|
||||
timestamp = strtoull(buf, NULL, 10);
|
||||
c++;
|
||||
prefix = c;
|
||||
path = strchr(c, ':');
|
||||
if (!path) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
*path = 0;
|
||||
path++;
|
||||
|
||||
/* GDB and elfutils both stat /usr/lib/debug directly when looking up
|
||||
* debuginfo, so avoid the download for "/.tar"; the associated cache
|
||||
* directories already exist by this point.
|
||||
*/
|
||||
if (strlen(path) == 1 && strcmp(path, "/") == 0) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
/* GDB and elfutils both stat /usr/lib/debug directly when looking up
|
||||
* debuginfo, so avoid the download for "/.tar"; the associated cache
|
||||
* directories already exist by this point.
|
||||
*/
|
||||
if (strlen(path) == 1 && strcmp(path, "/") == 0) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strstr(path, "..") || strstr(prefix, "..") || strstr(path, "'") || strstr(path, ";")) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if (strstr(path, "..") || strstr(prefix, "..") || strstr(path, "'") || strstr(path, ";")) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strcmp(prefix, "lib") !=0 && strcmp(prefix, "src") != 0) {
|
||||
/* invalid prefix */
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
url = NULL;
|
||||
if (asprintf(&url, "%s%s%s.tar", urls[urlcounter % 2], prefix, path) < 0) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if (strcmp(prefix, "lib") != 0 && strcmp(prefix, "src") != 0) {
|
||||
/* invalid prefix */
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
url = NULL;
|
||||
if (asprintf(&url, "%s%s%s.tar", urls[urlcounter % 2], prefix, path) < 0) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// printf("Getting url %s %i:%06i\n", url, before.tv_sec, before.tv_usec);
|
||||
ret = curl_get_file(url, prefix, timestamp);
|
||||
// printf("Getting url %s %i:%06i\n", url, before.tv_sec, before.tv_usec);
|
||||
ret = curl_get_file(url, prefix, timestamp);
|
||||
|
||||
switch (ret) {
|
||||
case 200:
|
||||
case 300:
|
||||
case 304:
|
||||
case 404:
|
||||
// ignore these error codes
|
||||
break;
|
||||
default:
|
||||
printf("Request for %s resulted in error %i\n", url, ret);
|
||||
break;
|
||||
}
|
||||
switch (ret) {
|
||||
case 200:
|
||||
case 300:
|
||||
case 304:
|
||||
case 404:
|
||||
// ignore these error codes
|
||||
break;
|
||||
default:
|
||||
printf("Request for %s resulted in error %i\n", url, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
gettimeofday(&after, NULL);
|
||||
if (timedelta(before, after) > 0.6)
|
||||
printf("Request for %s took %5.2f seconds (%i - %i)\n", url,
|
||||
after.tv_sec - before.tv_sec + (1.0*after.tv_usec - before.tv_usec) / 1000000.0, ret, (int)timestamp);
|
||||
gettimeofday(&after, NULL);
|
||||
if (timedelta(before, after) > 0.6)
|
||||
printf("Request for %s took %5.2f seconds (%i - %i)\n",
|
||||
url,
|
||||
after.tv_sec - before.tv_sec +
|
||||
(1.0 * after.tv_usec - before.tv_usec) / 1000000.0,
|
||||
ret,
|
||||
(int)timestamp);
|
||||
|
||||
/* tell the other side we're done with the download */
|
||||
write(fd, "ok", 3);
|
||||
close(fd);
|
||||
/* tell the other side we're done with the download */
|
||||
write(fd, "ok", 3);
|
||||
close(fd);
|
||||
|
||||
|
||||
free(url);
|
||||
return NULL;
|
||||
free(url);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int sockfd;
|
||||
struct sockaddr_un sun;
|
||||
int ret;
|
||||
int curl_done = 0;
|
||||
int sockfd;
|
||||
struct sockaddr_un sun;
|
||||
int ret;
|
||||
int curl_done = 0;
|
||||
|
||||
if (argc < -1)
|
||||
(void)argv;
|
||||
if (argc < -1)
|
||||
(void)argv;
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
signal(SIGPIPE,SIG_IGN);
|
||||
if (access("/var/cache/debuginfo/lib/", F_OK))
|
||||
system("mkdir -p /var/cache/debuginfo/lib/ &> /dev/null");
|
||||
if (access("/var/cache/debuginfo/src/", F_OK))
|
||||
system("mkdir -p /var/cache/debuginfo/src/ &> /dev/null");
|
||||
|
||||
if (access("/var/cache/debuginfo/lib/", F_OK))
|
||||
system("mkdir -p /var/cache/debuginfo/lib/ &> /dev/null");
|
||||
if (access("/var/cache/debuginfo/src/", F_OK))
|
||||
system("mkdir -p /var/cache/debuginfo/src/ &> /dev/null");
|
||||
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sockfd < 0)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sockfd < 0)
|
||||
return EXIT_FAILURE;
|
||||
sun.sun_family = AF_UNIX;
|
||||
strcpy(sun.sun_path, ":clr-debug-info");
|
||||
sun.sun_path[0] = 0; /* anonymous unix socket */
|
||||
|
||||
sun.sun_family = AF_UNIX;
|
||||
strcpy(sun.sun_path, ":clr-debug-info");
|
||||
sun.sun_path[0] = 0; /* anonymous unix socket */
|
||||
ret = bind(sockfd,
|
||||
(struct sockaddr *)&sun,
|
||||
offsetof(struct sockaddr_un, sun_path) + strlen(":clr-debug-info") + 1);
|
||||
if (ret < 0) {
|
||||
printf("Failed to bind:%s \n", strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ret = bind(sockfd, (struct sockaddr *)&sun, offsetof(struct sockaddr_un, sun_path) + strlen(":clr-debug-info") + 1);
|
||||
if (ret < 0) {
|
||||
printf("Failed to bind:%s \n", strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (listen(sockfd, 16) < 0) {
|
||||
printf("Failed to listen:%s \n", strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (listen(sockfd, 16) < 0) {
|
||||
printf("Failed to listen:%s \n", strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
while (1) {
|
||||
int clientsock;
|
||||
pthread_t thread;
|
||||
|
||||
malloc_trim(0);
|
||||
clientsock = accept(sockfd, NULL, NULL);
|
||||
|
||||
while (1) {
|
||||
int clientsock;
|
||||
pthread_t thread;
|
||||
|
||||
malloc_trim(0);
|
||||
clientsock = accept(sockfd, NULL, NULL);
|
||||
|
||||
if (!curl_done) {
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curl_done = 1;
|
||||
}
|
||||
|
||||
pthread_create(&thread, NULL, server_thread, (void *)(unsigned long)clientsock);
|
||||
pthread_detach(thread);
|
||||
}
|
||||
close(sockfd);
|
||||
if (!curl_done) {
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curl_done = 1;
|
||||
}
|
||||
|
||||
pthread_create(&thread, NULL, server_thread, (void *)(unsigned long)clientsock);
|
||||
pthread_detach(thread);
|
||||
}
|
||||
close(sockfd);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user