forked from KolibriOS/kolibrios
kpm: command line options
git-svn-id: svn://kolibrios.org@5737 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
d2cc18ec69
commit
4823ea9991
@ -20,14 +20,15 @@ INCLUDES+=-I$(SDK_DIR)/sources/freetype/include
|
|||||||
#DEFINES= -DDEBUG=1
|
#DEFINES= -DDEBUG=1
|
||||||
|
|
||||||
DEFINES= -DNDEBUG
|
DEFINES= -DNDEBUG
|
||||||
LIBS:= -lsupc++ -lgcc_eh -lc.dll -lapp -lgcc
|
LIBS:= -liberty -lsupc++ -lgcc_eh -lc.dll -lapp -lgcc
|
||||||
|
|
||||||
LIBPATH:= -L$(LIB_DIR) -L/home/autobuild/tools/win32/mingw32/lib
|
LIBPATH:= -L$(LIB_DIR) -L/home/autobuild/tools/win32/mingw32/lib
|
||||||
|
|
||||||
LDFLAGS = -static -nostdlib --stack 0x30000 -Map kpm.map -T$(SDK_DIR)/sources/newlib/app.lds --image-base 0
|
LDFLAGS = -static -nostdlib --stack 0x10000 -Map kpm.map -T$(SDK_DIR)/sources/newlib/app.lds --image-base 0
|
||||||
|
|
||||||
SOURCES = http.asm \
|
SOURCES = http.asm \
|
||||||
kpm.c \
|
kpm.c \
|
||||||
|
utils.c \
|
||||||
collection.cpp \
|
collection.cpp \
|
||||||
tinyxml/tinyxml.cpp \
|
tinyxml/tinyxml.cpp \
|
||||||
tinyxml/tinystr.cpp \
|
tinyxml/tinystr.cpp \
|
||||||
|
144
contrib/other/kpm/getopt.h
Normal file
144
contrib/other/kpm/getopt.h
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/* Declarations for getopt.
|
||||||
|
Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 2000,
|
||||||
|
2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
||||||
|
Bugs can be reported to bug-glibc@gnu.org.
|
||||||
|
|
||||||
|
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, 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. */
|
||||||
|
|
||||||
|
#ifndef _GETOPT_H
|
||||||
|
#define _GETOPT_H 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* For communication from `getopt' to the caller.
|
||||||
|
When `getopt' finds an option that takes an argument,
|
||||||
|
the argument value is returned here.
|
||||||
|
Also, when `ordering' is RETURN_IN_ORDER,
|
||||||
|
each non-option ARGV-element is returned here. */
|
||||||
|
|
||||||
|
extern char *optarg;
|
||||||
|
|
||||||
|
/* Index in ARGV of the next element to be scanned.
|
||||||
|
This is used for communication to and from the caller
|
||||||
|
and for communication between successive calls to `getopt'.
|
||||||
|
|
||||||
|
On entry to `getopt', zero means this is the first call; initialize.
|
||||||
|
|
||||||
|
When `getopt' returns -1, this is the index of the first of the
|
||||||
|
non-option elements that the caller should itself scan.
|
||||||
|
|
||||||
|
Otherwise, `optind' communicates from one call to the next
|
||||||
|
how much of ARGV has been scanned so far. */
|
||||||
|
|
||||||
|
extern int optind;
|
||||||
|
|
||||||
|
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||||
|
for unrecognized options. */
|
||||||
|
|
||||||
|
extern int opterr;
|
||||||
|
|
||||||
|
/* Set to an option character which was unrecognized. */
|
||||||
|
|
||||||
|
extern int optopt;
|
||||||
|
|
||||||
|
/* Describe the long-named options requested by the application.
|
||||||
|
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||||
|
of `struct option' terminated by an element containing a name which is
|
||||||
|
zero.
|
||||||
|
|
||||||
|
The field `has_arg' is:
|
||||||
|
no_argument (or 0) if the option does not take an argument,
|
||||||
|
required_argument (or 1) if the option requires an argument,
|
||||||
|
optional_argument (or 2) if the option takes an optional argument.
|
||||||
|
|
||||||
|
If the field `flag' is not NULL, it points to a variable that is set
|
||||||
|
to the value given in the field `val' when the option is found, but
|
||||||
|
left unchanged if the option is not found.
|
||||||
|
|
||||||
|
To have a long-named option do something other than set an `int' to
|
||||||
|
a compiled-in constant, such as set a value from `optarg', set the
|
||||||
|
option's `flag' field to zero and its `val' field to a nonzero
|
||||||
|
value (the equivalent single-letter option character, if there is
|
||||||
|
one). For long options that have a zero `flag' field, `getopt'
|
||||||
|
returns the contents of the `val' field. */
|
||||||
|
|
||||||
|
struct option
|
||||||
|
{
|
||||||
|
#if defined (__STDC__) && __STDC__
|
||||||
|
const char *name;
|
||||||
|
#else
|
||||||
|
char *name;
|
||||||
|
#endif
|
||||||
|
/* has_arg can't be an enum because some compilers complain about
|
||||||
|
type mismatches in all the code that assumes it is an int. */
|
||||||
|
int has_arg;
|
||||||
|
int *flag;
|
||||||
|
int val;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||||
|
|
||||||
|
#define no_argument 0
|
||||||
|
#define required_argument 1
|
||||||
|
#define optional_argument 2
|
||||||
|
|
||||||
|
#if defined (__STDC__) && __STDC__
|
||||||
|
/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is
|
||||||
|
undefined, we haven't run the autoconf check so provide the
|
||||||
|
declaration without arguments. If it is 0, we checked and failed
|
||||||
|
to find the declaration so provide a fully prototyped one. If it
|
||||||
|
is 1, we found it so don't provide any declaration at all. */
|
||||||
|
#if !HAVE_DECL_GETOPT
|
||||||
|
#if defined (__GNU_LIBRARY__) || defined (HAVE_DECL_GETOPT)
|
||||||
|
/* Many other libraries have conflicting prototypes for getopt, with
|
||||||
|
differences in the consts, in unistd.h. To avoid compilation
|
||||||
|
errors, only prototype getopt for the GNU C library. */
|
||||||
|
extern int getopt (int argc, char *const *argv, const char *shortopts);
|
||||||
|
#else
|
||||||
|
#ifndef __cplusplus
|
||||||
|
extern int getopt ();
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
#endif
|
||||||
|
#endif /* !HAVE_DECL_GETOPT */
|
||||||
|
|
||||||
|
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||||
|
const struct option *longopts, int *longind);
|
||||||
|
extern int getopt_long_only (int argc, char *const *argv,
|
||||||
|
const char *shortopts,
|
||||||
|
const struct option *longopts, int *longind);
|
||||||
|
|
||||||
|
/* Internal only. Users should not call this directly. */
|
||||||
|
extern int _getopt_internal (int argc, char *const *argv,
|
||||||
|
const char *shortopts,
|
||||||
|
const struct option *longopts, int *longind,
|
||||||
|
int long_only);
|
||||||
|
#else /* not __STDC__ */
|
||||||
|
extern int getopt ();
|
||||||
|
extern int getopt_long ();
|
||||||
|
extern int getopt_long_only ();
|
||||||
|
|
||||||
|
extern int _getopt_internal ();
|
||||||
|
#endif /* __STDC__ */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* getopt.h */
|
@ -52,5 +52,8 @@ unsigned __stdcall con_set_flags(unsigned new_flags);
|
|||||||
void __stdcall con_cls(void);
|
void __stdcall con_cls(void);
|
||||||
void __stdcall con_write_asciiz(const char* string);
|
void __stdcall con_write_asciiz(const char* string);
|
||||||
|
|
||||||
|
char *make_url(const char *name);
|
||||||
|
char *make_tmp_path(const char *path);
|
||||||
|
char *make_cache_path(const char *path);
|
||||||
|
|
||||||
#endif /* __HTTP_H__ */
|
#endif /* __HTTP_H__ */
|
||||||
|
@ -1,130 +1,41 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <kos32sys.h>
|
#include <kos32sys.h>
|
||||||
#include <sys/kos_io.h>
|
#include <sys/kos_io.h>
|
||||||
|
|
||||||
|
#include "getopt.h"
|
||||||
#include "package.h"
|
#include "package.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
|
||||||
#define BUFFSIZE (64*1024)
|
#define BUFFSIZE (64*1024)
|
||||||
|
|
||||||
char conbuf[256];
|
extern char conbuf[256];
|
||||||
|
|
||||||
char *make_url(const char *name)
|
#define OPTION_STD_BASE 150
|
||||||
|
|
||||||
|
enum option_values
|
||||||
{
|
{
|
||||||
static char url_buf[128] = "http://ftp.kolibrios.org/users/Serge/new/OS/";
|
OPTION_HELP = OPTION_STD_BASE,
|
||||||
strcpy(&url_buf[44], name);
|
OPTION_LIST_PACKAGES,
|
||||||
return url_buf;
|
OPTION_LIST_INSTALLED
|
||||||
};
|
};
|
||||||
|
|
||||||
char *make_tmp_path(const char *path)
|
static const struct option longopts[] =
|
||||||
{
|
{
|
||||||
static char path_buf[64] = "/tmp0/1/";
|
{"list-packages", no_argument, NULL, OPTION_LIST_PACKAGES},
|
||||||
strcpy(&path_buf[8], path);
|
{"list-installed",no_argument, NULL, OPTION_LIST_INSTALLED},
|
||||||
return path_buf;
|
{NULL,0,NULL,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
char *make_cache_path(const char *path)
|
|
||||||
{
|
|
||||||
static char path_buf[64] = "/kolibrios/kpm/cache/";
|
|
||||||
strcpy(&path_buf[21], path);
|
|
||||||
return path_buf;
|
|
||||||
};
|
|
||||||
|
|
||||||
int http_load_file(const char *path, const char *url)
|
|
||||||
{
|
|
||||||
http_t *http;
|
|
||||||
int received = 0;
|
|
||||||
int offset = 0;
|
|
||||||
int tail;
|
|
||||||
char *buf;
|
|
||||||
int fd;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
buf = user_alloc(BUFFSIZE);
|
|
||||||
for(i = 0; i < 16; i++)
|
|
||||||
buf[i*4096] = 0;
|
|
||||||
|
|
||||||
fd = open(path, O_CREAT|O_WRONLY);
|
|
||||||
if(fd == -1)
|
|
||||||
{
|
|
||||||
user_free(buf);
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
http = http_get(url, NULL,FLAG_STREAM|FLAG_REUSE_BUFFER, NULL);
|
|
||||||
if(http == NULL)
|
|
||||||
goto err_get;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if(http_receive_with_retry(http, 500) == 0)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
|
|
||||||
// if(http->flags & 0xffff0000)
|
|
||||||
// break;
|
|
||||||
|
|
||||||
count = http->content_received - received;
|
|
||||||
if(count+offset <= BUFFSIZE)
|
|
||||||
{
|
|
||||||
memcpy(buf+offset, http->content_ptr, count);
|
|
||||||
offset+= count;
|
|
||||||
}
else
|
|
||||||
{
|
|
||||||
tail = count+offset-BUFFSIZE;
|
|
||||||
count = BUFFSIZE - offset;
|
|
||||||
if(count)
|
|
||||||
{
|
|
||||||
memcpy(buf+offset, http->content_ptr, count);
|
|
||||||
offset = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
write(fd, buf, BUFFSIZE);
|
|
||||||
|
|
||||||
if(tail)
|
|
||||||
{
|
|
||||||
memcpy(buf, http->content_ptr+count, tail);
|
|
||||||
offset = tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(conbuf, "%d bytes loaded\r", http->content_received);
|
|
||||||
con_write_asciiz(conbuf);
|
|
||||||
|
|
||||||
}
|
|
||||||
received = http->content_received;
|
|
||||||
}
|
|
||||||
else break;
|
|
||||||
|
|
||||||
}while( (http->flags & FLAG_GOT_ALL_DATA) == 0);
|
|
||||||
|
|
||||||
if(offset)
|
|
||||||
{
|
|
||||||
write(fd, buf, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ftruncate(fd, received);
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
if(http->content_ptr)
|
|
||||||
user_free(http->content_ptr);
|
|
||||||
http_free(http);
|
|
||||||
|
|
||||||
user_free(buf);
|
|
||||||
|
|
||||||
return received;
|
|
||||||
|
|
||||||
err_get:
|
|
||||||
printf("HTTP GET failed\n");
|
|
||||||
return received;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
LIST_HEAD(server_list);
|
||||||
|
LIST_HEAD(download_list);
|
||||||
|
LIST_HEAD(cache_list);
|
||||||
|
LIST_HEAD(local_list);
|
||||||
|
LIST_HEAD(task_list);
|
||||||
|
|
||||||
int count;
|
int count;
|
||||||
char *cache_path;
|
char *cache_path;
|
||||||
char *tmp_path;
|
char *tmp_path;
|
||||||
@ -132,6 +43,8 @@ int main(int argc, char *argv[])
|
|||||||
if(http_init())
|
if(http_init())
|
||||||
goto err_init;
|
goto err_init;
|
||||||
|
|
||||||
|
set_cwd("/tmp0/1");
|
||||||
|
|
||||||
con_init(80, 25, 80, 250, "Kolibri package manager");
|
con_init(80, 25, 80, 250, "Kolibri package manager");
|
||||||
|
|
||||||
tmp_path = make_tmp_path("packages.xml");
|
tmp_path = make_tmp_path("packages.xml");
|
||||||
@ -139,14 +52,45 @@ int main(int argc, char *argv[])
|
|||||||
count = http_load_file(tmp_path, make_url("packages.xml"));
|
count = http_load_file(tmp_path, make_url("packages.xml"));
|
||||||
|
|
||||||
if(count)
|
if(count)
|
||||||
|
build_server_list(&server_list, tmp_path);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
val = getopt_long_only(argc, argv,"",longopts, &index);
|
||||||
|
|
||||||
|
if(val == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch(val)
|
||||||
|
{
|
||||||
|
case OPTION_LIST_PACKAGES:
|
||||||
|
sprintf(conbuf,"available packages:\n\n");
|
||||||
|
con_write_asciiz(conbuf);
|
||||||
|
print_pkg_list(&server_list);
|
||||||
|
con_exit(0);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case OPTION_LIST_INSTALLED:
|
||||||
|
sprintf(conbuf,"installed packages:\n\n");
|
||||||
|
con_write_asciiz(conbuf);
|
||||||
|
print_pkg_list(&local_list);
|
||||||
|
con_exit(0);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
{
|
{
|
||||||
collection_t *collection;
|
|
||||||
package_t *pkg;
|
package_t *pkg;
|
||||||
LIST_HEAD(install_list);
|
LIST_HEAD(install_list);
|
||||||
LIST_HEAD(download_list);
|
LIST_HEAD(download_list);
|
||||||
|
|
||||||
collection = load_collection_file(tmp_path);
|
|
||||||
|
|
||||||
if(collection && build_install_list(&install_list, collection))
|
if(collection && build_install_list(&install_list, collection))
|
||||||
{
|
{
|
||||||
if(build_download_list(&download_list, &install_list))
|
if(build_download_list(&download_list, &install_list))
|
||||||
@ -161,11 +105,10 @@ int main(int argc, char *argv[])
|
|||||||
con_write_asciiz(conbuf);
|
con_write_asciiz(conbuf);
|
||||||
};
|
};
|
||||||
|
|
||||||
set_cwd("/tmp0/1");
|
|
||||||
|
|
||||||
do_install(&install_list);
|
do_install(&install_list);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
con_exit(0);
|
con_exit(0);
|
||||||
|
|
||||||
@ -176,97 +119,6 @@ err_init:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int build_install_list(list_t *list, collection_t *collection)
|
|
||||||
{
|
|
||||||
pkg_group_t *gr;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
list_for_each_entry(gr, &collection->groups, list)
|
|
||||||
{
|
|
||||||
package_t *pkg, *tmp;
|
|
||||||
|
|
||||||
list_for_each_entry(tmp, &gr->packages, list)
|
|
||||||
{
|
|
||||||
pkg = (package_t*)malloc(sizeof(package_t));
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&pkg->file_list);
|
|
||||||
pkg->id = tmp->id;
|
|
||||||
pkg->name = strdup(tmp->name);
|
|
||||||
pkg->version = strdup(tmp->version);
|
|
||||||
pkg->filename = strdup(tmp->filename);
|
|
||||||
pkg->description = strdup(tmp->description);
|
|
||||||
list_add_tail(&pkg->list, list);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
int build_download_list(list_t *download, list_t *src)
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
char *cache_path;
|
|
||||||
package_t *pkg, *tmp;
|
|
||||||
fileinfo_t info;
|
|
||||||
list_for_each_entry(tmp, src, list)
|
|
||||||
{
|
|
||||||
cache_path = make_cache_path(tmp->filename);
|
|
||||||
|
|
||||||
if( get_fileinfo(cache_path, &info) != 0)
|
|
||||||
{
|
|
||||||
pkg = (package_t*)malloc(sizeof(package_t));
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&pkg->file_list);
|
|
||||||
pkg->id = tmp->id;
|
|
||||||
pkg->name = strdup(tmp->name);
|
|
||||||
pkg->version = strdup(tmp->version);
|
|
||||||
pkg->filename = strdup(tmp->filename);
|
|
||||||
pkg->description = strdup(tmp->description);
|
|
||||||
list_add_tail(&pkg->list, download);
|
|
||||||
count++;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
};
|
|
||||||
|
|
||||||
void do_download(list_t *download_list)
|
|
||||||
{
|
|
||||||
package_t *pkg, *tmp;
|
|
||||||
char *cache_path;
|
|
||||||
int count;
|
|
||||||
|
|
||||||
list_for_each_entry_safe(pkg, tmp, download_list, list)
|
|
||||||
{
|
|
||||||
sprintf(conbuf,"package %s-%s\n", pkg->name, pkg->version);
|
|
||||||
con_write_asciiz(conbuf);
|
|
||||||
cache_path = make_cache_path(pkg->filename);
|
|
||||||
count = http_load_file(cache_path, make_url(pkg->filename));
|
|
||||||
sprintf(conbuf,"%s %d bytes loaded\n",cache_path, count);
|
|
||||||
con_write_asciiz(conbuf);
|
|
||||||
if( !test_archive(cache_path))
|
|
||||||
list_del_pkg(pkg);
|
|
||||||
else
|
|
||||||
unlink(cache_path);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove_missing_packages(list_t *install, list_t *missed)
|
|
||||||
{
|
|
||||||
package_t *mpkg, *mtmp, *ipkg, *itmp;
|
|
||||||
|
|
||||||
list_for_each_entry_safe(mpkg, mtmp, missed, list)
|
|
||||||
{
|
|
||||||
list_for_each_entry_safe(ipkg, itmp, install, list)
|
|
||||||
{
|
|
||||||
if(ipkg->id == mpkg->id)
|
|
||||||
{
|
|
||||||
sprintf(conbuf,"skip missing package %s-%s\n", ipkg->name, ipkg->version);
|
|
||||||
con_write_asciiz(conbuf);
|
|
||||||
list_del_pkg(ipkg);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
list_del_pkg(mpkg);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,10 +43,12 @@ static inline void list_del_pkg(package_t *pkg)
|
|||||||
collection_t* load_collection_file(const char *name);
|
collection_t* load_collection_file(const char *name);
|
||||||
collection_t* load_collection_buffer(const char *buffer);
|
collection_t* load_collection_buffer(const char *buffer);
|
||||||
|
|
||||||
|
int build_server_list(list_t *slist, const char *path);
|
||||||
int build_install_list(list_t *list, collection_t *collection);
|
int build_install_list(list_t *list, collection_t *collection);
|
||||||
int build_download_list(list_t *download, list_t *src);
|
int build_download_list(list_t *download, list_t *src);
|
||||||
void remove_missing_packages(list_t *install, list_t *missed);
|
void remove_missing_packages(list_t *install, list_t *missed);
|
||||||
char *make_cache_path(const char *path);
|
char *make_cache_path(const char *path);
|
||||||
|
void print_pkg_list(list_t *list);
|
||||||
|
|
||||||
void do_download(list_t *download);
|
void do_download(list_t *download);
|
||||||
void do_install(list_t *install);
|
void do_install(list_t *install);
|
||||||
|
266
contrib/other/kpm/utils.c
Normal file
266
contrib/other/kpm/utils.c
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <kos32sys.h>
|
||||||
|
#include <sys/kos_io.h>
|
||||||
|
#include "package.h"
|
||||||
|
#include "http.h"
|
||||||
|
|
||||||
|
#define BUFFSIZE (64*1024)
|
||||||
|
|
||||||
|
char conbuf[256];
|
||||||
|
|
||||||
|
|
||||||
|
char *make_url(const char *name)
|
||||||
|
{
|
||||||
|
static char url_buf[128] = "http://ftp.kolibrios.org/users/Serge/new/OS/";
|
||||||
|
strcpy(&url_buf[44], name);
|
||||||
|
return url_buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
char *make_tmp_path(const char *path)
|
||||||
|
{
|
||||||
|
static char path_buf[64] = "/tmp0/1/";
|
||||||
|
strcpy(&path_buf[8], path);
|
||||||
|
return path_buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
char *make_cache_path(const char *path)
|
||||||
|
{
|
||||||
|
static char path_buf[64] = "/kolibrios/kpm/cache/";
|
||||||
|
strcpy(&path_buf[21], path);
|
||||||
|
return path_buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
int http_load_file(const char *path, const char *url)
|
||||||
|
{
|
||||||
|
http_t *http;
|
||||||
|
int received = 0;
|
||||||
|
int offset = 0;
|
||||||
|
int tail;
|
||||||
|
char *buf;
|
||||||
|
int fd;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
buf = user_alloc(BUFFSIZE);
|
||||||
|
for(i = 0; i < 16; i++)
|
||||||
|
buf[i*4096] = 0;
|
||||||
|
|
||||||
|
fd = open(path, O_CREAT|O_WRONLY);
|
||||||
|
if(fd == -1)
|
||||||
|
{
|
||||||
|
user_free(buf);
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
http = http_get(url, NULL,FLAG_STREAM|FLAG_REUSE_BUFFER, NULL);
|
||||||
|
if(http == NULL)
|
||||||
|
goto err_get;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if(http_receive_with_retry(http, 500) == 0)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
|
||||||
|
// if(http->flags & 0xffff0000)
|
||||||
|
// break;
|
||||||
|
|
||||||
|
count = http->content_received - received;
|
||||||
|
if(count+offset <= BUFFSIZE)
|
||||||
|
{
|
||||||
|
memcpy(buf+offset, http->content_ptr, count);
|
||||||
|
offset+= count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tail = count+offset-BUFFSIZE;
|
||||||
|
count = BUFFSIZE - offset;
|
||||||
|
if(count)
|
||||||
|
{
|
||||||
|
memcpy(buf+offset, http->content_ptr, count);
|
||||||
|
offset = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
write(fd, buf, BUFFSIZE);
|
||||||
|
|
||||||
|
if(tail)
|
||||||
|
{
|
||||||
|
memcpy(buf, http->content_ptr+count, tail);
|
||||||
|
offset = tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(conbuf, "%d bytes loaded\r", http->content_received);
|
||||||
|
con_write_asciiz(conbuf);
|
||||||
|
|
||||||
|
}
|
||||||
|
received = http->content_received;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
|
||||||
|
}while( (http->flags & FLAG_GOT_ALL_DATA) == 0);
|
||||||
|
|
||||||
|
if(offset)
|
||||||
|
{
|
||||||
|
write(fd, buf, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ftruncate(fd, received);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
if(http->content_ptr)
|
||||||
|
user_free(http->content_ptr);
|
||||||
|
http_free(http);
|
||||||
|
|
||||||
|
user_free(buf);
|
||||||
|
|
||||||
|
return received;
|
||||||
|
|
||||||
|
err_get:
|
||||||
|
printf("HTTP GET failed\n");
|
||||||
|
return received;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int build_download_list(list_t *download, list_t *src)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
char *cache_path;
|
||||||
|
package_t *pkg, *tmp;
|
||||||
|
fileinfo_t info;
|
||||||
|
list_for_each_entry(tmp, src, list)
|
||||||
|
{
|
||||||
|
cache_path = make_cache_path(tmp->filename);
|
||||||
|
|
||||||
|
if( get_fileinfo(cache_path, &info) != 0)
|
||||||
|
{
|
||||||
|
pkg = (package_t*)malloc(sizeof(package_t));
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&pkg->file_list);
|
||||||
|
pkg->id = tmp->id;
|
||||||
|
pkg->name = strdup(tmp->name);
|
||||||
|
pkg->version = strdup(tmp->version);
|
||||||
|
pkg->filename = strdup(tmp->filename);
|
||||||
|
pkg->description = strdup(tmp->description);
|
||||||
|
list_add_tail(&pkg->list, download);
|
||||||
|
count++;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
};
|
||||||
|
|
||||||
|
void do_download(list_t *download_list)
|
||||||
|
{
|
||||||
|
package_t *pkg, *tmp;
|
||||||
|
char *cache_path;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
list_for_each_entry_safe(pkg, tmp, download_list, list)
|
||||||
|
{
|
||||||
|
sprintf(conbuf,"package %s-%s\n", pkg->name, pkg->version);
|
||||||
|
con_write_asciiz(conbuf);
|
||||||
|
cache_path = make_cache_path(pkg->filename);
|
||||||
|
count = http_load_file(cache_path, make_url(pkg->filename));
|
||||||
|
sprintf(conbuf,"%s %d bytes loaded\n",cache_path, count);
|
||||||
|
con_write_asciiz(conbuf);
|
||||||
|
if( !test_archive(cache_path))
|
||||||
|
list_del_pkg(pkg);
|
||||||
|
else
|
||||||
|
unlink(cache_path);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove_missing_packages(list_t *install, list_t *missed)
|
||||||
|
{
|
||||||
|
package_t *mpkg, *mtmp, *ipkg, *itmp;
|
||||||
|
|
||||||
|
list_for_each_entry_safe(mpkg, mtmp, missed, list)
|
||||||
|
{
|
||||||
|
list_for_each_entry_safe(ipkg, itmp, install, list)
|
||||||
|
{
|
||||||
|
if(ipkg->id == mpkg->id)
|
||||||
|
{
|
||||||
|
sprintf(conbuf,"skip missing package %s-%s\n", ipkg->name, ipkg->version);
|
||||||
|
con_write_asciiz(conbuf);
|
||||||
|
list_del_pkg(ipkg);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
list_del_pkg(mpkg);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
int build_install_list(list_t *list, collection_t *collection)
|
||||||
|
{
|
||||||
|
pkg_group_t *gr;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
list_for_each_entry(gr, &collection->groups, list)
|
||||||
|
{
|
||||||
|
package_t *pkg, *tmp;
|
||||||
|
|
||||||
|
list_for_each_entry(tmp, &gr->packages, list)
|
||||||
|
{
|
||||||
|
pkg = (package_t*)malloc(sizeof(package_t));
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&pkg->file_list);
|
||||||
|
pkg->id = tmp->id;
|
||||||
|
pkg->name = strdup(tmp->name);
|
||||||
|
pkg->version = strdup(tmp->version);
|
||||||
|
pkg->filename = strdup(tmp->filename);
|
||||||
|
pkg->description = strdup(tmp->description);
|
||||||
|
list_add_tail(&pkg->list, list);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int build_server_list(list_t *slist, const char *path)
|
||||||
|
{
|
||||||
|
collection_t *collection;
|
||||||
|
package_t *pkg;
|
||||||
|
LIST_HEAD(install_list);
|
||||||
|
LIST_HEAD(download_list);
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
collection = load_collection_file(path);
|
||||||
|
|
||||||
|
if(collection)
|
||||||
|
{
|
||||||
|
pkg_group_t *gr;
|
||||||
|
|
||||||
|
list_for_each_entry(gr, &collection->groups, list)
|
||||||
|
{
|
||||||
|
package_t *pkg, *tmp;
|
||||||
|
|
||||||
|
list_for_each_entry(tmp, &gr->packages, list)
|
||||||
|
{
|
||||||
|
pkg = (package_t*)malloc(sizeof(package_t));
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&pkg->file_list);
|
||||||
|
pkg->id = tmp->id;
|
||||||
|
pkg->name = strdup(tmp->name);
|
||||||
|
pkg->version = strdup(tmp->version);
|
||||||
|
pkg->filename = strdup(tmp->filename);
|
||||||
|
pkg->description = strdup(tmp->description);
|
||||||
|
list_add_tail(&pkg->list, slist);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_pkg_list(list_t *list)
|
||||||
|
{
|
||||||
|
package_t *pkg;
|
||||||
|
|
||||||
|
list_for_each_entry(pkg, list, list)
|
||||||
|
{
|
||||||
|
sprintf(conbuf,"%s-%s\n", pkg->name, pkg->version);
|
||||||
|
con_write_asciiz(conbuf);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user