first commit

This commit is contained in:
SANO Masatoshi 2014-07-30 03:09:01 +09:00
commit 001d2878c3
17 changed files with 1335 additions and 0 deletions

0
AUTHORS Normal file
View file

0
ChangeLog Normal file
View file

2
Makefile.am Normal file
View file

@ -0,0 +1,2 @@
SUBDIRS = src

0
NEWS Normal file
View file

0
README Normal file
View file

30
configure.ac Normal file
View file

@ -0,0 +1,30 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([lsp],[0.0.0],snmsts@gmail.com)
AM_CONFIG_HEADER(config.h)
AC_CONFIG_FILES([Makefile src/Makefile])
AC_CONFIG_SRCDIR([src/lsp.c])
AM_INIT_AUTOMAKE
# Checks for programs.
AC_PROG_CC
#AC_PROG_INSTALL
# Checks for libraries.
AC_CHECK_LIB([curl], [curl_global_init],[],[AC_MSG_ERROR([libcurl development files required])])
AC_CHECK_LIB([archive], [archive_read_open_filename],[],[AC_MSG_ERROR([libarchive is needed to compile lsp])])
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(stdlib.h stdio.h sys/stat.h archive.h)
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT

3
src/Makefile.am Normal file
View file

@ -0,0 +1,3 @@
bin_PROGRAMS = lsp
lsp_SOURCES = lsp.c opt.c download.c util.c archive.c cmd_version.c cmd_install.c cmd_run.c
include_HEADERS = opt.h util.h

176
src/archive.c Normal file
View file

@ -0,0 +1,176 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <archive.h>
#include <archive_entry.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "util.h"
static void errmsg(const char *);
static int extract(const char *filename, int do_extract, int flags,const char* outputpath);
static int copy_data(struct archive *, struct archive *);
static void msg(const char *);
static int verbose = 0;
int cmd_tar(int argc, const char **argv)
{
const char *filename = NULL;
const char *outputpath = NULL;
int compress, flags, mode, opt;
(void)argc;
mode = 'x';
verbose = 0;
compress = '\0';
flags = ARCHIVE_EXTRACT_TIME;
/* Among other sins, getopt(3) pulls in printf(3). */
argv--;
while (*++argv != NULL && **argv == '-') {
const char *p = *argv + 1;
while ((opt = *p++) != '\0') {
switch (opt) {
case 'f':
if (*p != '\0')
filename = p;
else
filename = *++argv;
p += strlen(p);
break;
case 'C':
if (*p != '\0')
outputpath = p;
else
outputpath = *++argv;
p += strlen(p);
break;
case 'p':
flags |= ARCHIVE_EXTRACT_PERM;
flags |= ARCHIVE_EXTRACT_ACL;
flags |= ARCHIVE_EXTRACT_FFLAGS;
break;
case 't':
mode = opt;
break;
case 'v':
verbose++;
break;
case 'x':
mode = opt;
break;
}
}
}
switch (mode) {
case 't':
extract(filename, 0, flags,outputpath);
break;
case 'x':
extract(filename, 1, flags,outputpath);
break;
}
return (0);
}
static int
extract(const char *filename, int do_extract, int flags,const char* outputpath)
{
struct archive *a;
struct archive *ext;
struct archive_entry *entry;
int r;
a = archive_read_new();
ext = archive_write_disk_new();
archive_write_disk_set_options(ext, flags);
archive_read_support_filter_bzip2(a);
archive_read_support_filter_gzip(a);
archive_read_support_format_tar(a);
#ifndef NO_LOOKUP
archive_write_disk_set_standard_lookup(ext);
#endif
if (filename != NULL && strcmp(filename, "-") == 0)
filename = NULL;
if ((r = archive_read_open_filename(a, filename, 10240))) {
errmsg(archive_error_string(a));
errmsg("\n");
exit(r);
}
for (;;) {
r = archive_read_next_header(a, &entry);
if (r == ARCHIVE_EOF)
break;
if (r != ARCHIVE_OK) {
errmsg(archive_error_string(a));
errmsg("\n");
exit(EXIT_FAILURE);
}
if (verbose && do_extract)
msg("x ");
if (verbose || !do_extract)
msg(archive_entry_pathname(entry));
if(outputpath) {
char* p=s_cat2(q(outputpath),q(archive_entry_pathname(entry)));
archive_entry_copy_pathname(entry,p);
s(p);
}
if (do_extract) {
r = archive_write_header(ext, entry);
if (r != ARCHIVE_OK)
errmsg(archive_error_string(a));
else
copy_data(a, ext);
}
if (verbose || !do_extract)
msg("\n");
}
archive_read_close(a);
archive_read_free(a);
}
static int
copy_data(struct archive *ar, struct archive *aw)
{
int r;
const void *buff;
size_t size;
int64_t offset;
for (;;) {
r = archive_read_data_block(ar, &buff, &size, &offset);
if (r == ARCHIVE_EOF) {
errmsg(archive_error_string(ar));
return (ARCHIVE_OK);
}
if (r != ARCHIVE_OK)
return (r);
r = archive_write_data_block(aw, buff, size, offset);
if (r != ARCHIVE_OK) {
errmsg(archive_error_string(ar));
return (r);
}
}
}
static void
msg(const char *m)
{
int ret=write(1, m, strlen(m));
}
static void
errmsg(const char *m)
{
int ret;
if (m != NULL) {
ret=write(2, m, strlen(m));
}
}

300
src/cmd_install.c Normal file
View file

@ -0,0 +1,300 @@
#include <stdio.h>
#include <stdlib.h>
#include "util.h"
static int in_resume=0;
static char *flags =NULL;
typedef int (*install_cmds)(char* impl,char* version);
install_cmds *cmds=NULL;
int installed_p(char* impl,char* version)
{
int ret;
char* i;
if(strcmp(impl,"sbcl-bin")==0){
impl="sbcl";
i=s_cat(homedir(),q("impls/"),q(impl),q("-"),q(version),q("/"),NULL);
}
ret=directory_exist_p(i);
s(i);
return ret;
}
int install_running_p(char* impl,char* version)
{
/* TBD */
return 0;
}
int start(char* impl,char* version)
{
char* home= homedir();
char* p;
ensure_directories_exist(home);
if(installed_p(impl,version)) {
printf("%s-%s are already installed.if you intend to reinstall by (TBD).\n",impl,version);
return 0;
}
if(install_running_p(impl,version)) {
printf("It seems running installation process for $1-$2.\n");
return 0;
}
if(strcmp(impl,"sbcl")==0 && NULL==get_opt("sbcl-compiler")) {
printf("compiler variable 'sbcl-compiler' should be specified");
return 0;
}
/*trap "exit 1" HUP INT PIPE QUIT TERM*/
/*trap "rm -f $CIM_HOME/tmp/$1-$2.lock" EXIT*/
p=cat(home,"tmp/",impl,"-",version,"/",NULL);
ensure_directories_exist(p);
s(p);
p=cat(home,"tmp/",impl,"-",version,".lock",NULL);
touch(p);
s(p);
s(home);
return 1;
}
char* bz2distp(char* impl)
{
/* TBD rename function */
if(strcmp(impl,"sbcl")==0||
strcmp(impl,"sbcl-bin")==0||
strcmp(impl,"alisp")==0) {
return "bz2";
}
return "gz";
}
char* get_default_version(char* impl)
{
/* TBD */
if(strcmp(impl,"sbcl")==0) {
return q("1.2.1");
}else if(strcmp(impl,"sbcl-bin")==0) {
return s_cat(get_default_version("sbcl"),q("-"),uname_m(),q("-"),uname(),NULL);
}
}
char* get_download_path(char** impl,char** version)
{
if(strcmp(*impl,"sbcl")==0 && *version) {
return cat("http://sourceforge.net/projects/sbcl/files/sbcl/",*version,
"/sbcl-",*version,"-source.tar.bz2",NULL);
}else if(strcmp(*impl,"sbcl-bin")==0) {
return q("http://prdownloads.sourceforge.net/sbcl/sbcl-1.2.1-x86-64-linux-binary.tar.bz2");
}
return NULL;
}
int download(char* impl,char* version)
{
char* home= homedir();
char* url;
char* impl_archive;
printf("Donwloading archive.\n");
url=get_download_path(&impl,&version);
if(url) {
impl_archive=cat(home,"archives/",impl,"-",version,".tar.",bz2distp(impl),NULL);
ensure_directories_exist(impl_archive);
/* pipe connect for logging cim_with_output_control */
if(download_simple(url,impl_archive,0)) {
printf("Failed to Download.\n");
return 0;
/* fail */
}else{
printf("download done:%s\n",url);
}
}
s(impl_archive);
s(url);
s(home);
return 1;
}
int expand(char* impl,char* version)
{
char* home= homedir();
char* argv[5]={"-xf",NULL,"-C",NULL,NULL};
int argc=4;
char* archive;
char* dist_path;
archive=cat(impl,"-",version,".tar.",bz2distp(impl),NULL);
if(strcmp(impl,"sbcl-bin")==0) {
impl="sbcl";
}else {
}
version=q(version);
dist_path=cat(home,"src/",impl,"-",version,"/",NULL);
printf("Extracting archive. %s to %s\n",archive,dist_path);
delete_directory(dist_path,1);
ensure_directories_exist(dist_path);
/* pipe connect for logging cim_with_output_control */
argv[1]=cat(home,"archives/",archive,NULL);
argv[3]=cat(home,"src/",NULL);
cmd_tar(argc,argv);
s(argv[1]);
s(argv[3]);
s(dist_path);
s(archive);
s(home);
s(version);
return 1;
}
int configure(char* impl,char* version)
{
char* home= homedir();
char* confgcache= cat(home,"/src/",impl,"-",version,"/src/confg.cache",NULL);
char* cd;
char* configure;
int ret;
if(in_resume) {
delete_file(confgcache);
}
if(flags==NULL) {
flags=q("");
}
if(strcmp("gcl",impl)==0) {
flags=s_cat(flags,q(" --enable-ansi"));
}
if(strcmp("ecl",impl)==0 ||strcmp("ecl",impl)==0 || strcmp("clisp",impl)==0) {
flags=s_cat(flags,q(" --mandir="),q(home),q("/share/man"));
}
printf("Configuring %s-%s\n",impl,version);
cd=cat(home,"src/",impl,"-",version,NULL);
printf ("cd:%s\n",cd);
change_directory(cd);
/* pipe connect for logging cim_with_output_control */
configure=cat("./configure ",flags," --prefix=",home,"/impls/",impl,"-",version,NULL);
ret=system(configure);
s(configure);
s(cd);
s(confgcache);
s(home);
}
/*int sbcl_ensure_impl(char* impl,char* version) {
int ret=1;
char* bin_version;
printf((bin_version=q("Finding Lisp impl to build sbcl.\n")));
char* sbcl_bin_url=get_download_path("sbcl-bin",bin_version);
if(sbcl_bin_url){
if(!directory_exist_p()) {
}
s(sbcl_bin_url);
}else {
printf("can't download sbcl\n");
ret=0;
}
s(bin_version);
return ret;
}
*/
int sbcl_make(char* impl,char* version) {
char* home=homedir();
char* src=cat(home,"src/",impl,"-",version,NULL);
char* cmd=cat("sh make.sh \"","sbcl","\" ","--prefix=\"",home,"impls/",impl,"-",version,"\"",NULL);
printf("Building %s-%s\n",impl,version);
change_directory(src);
printf("cmd:%s\n",cmd);
system(cmd);
/* pipe connect for logging cim_with_output_control */
s(home),s(src),s(cmd);
}
int sbcl_install(char* impl,char* version) {
#ifndef _WIN32
int ret=1;
char* home= homedir();
if(strcmp(impl,"sbcl-bin")==0) {
impl="sbcl";
}
char* impl_path= cat(home,"impls/",impl,"-",version,NULL);
char* src=cat(home,"src/",impl,"-",version,NULL);
char* sbcl_home=cat(impl_path,"/lib/sbcl",NULL);
char* install_root=q(impl_path);
impl="sbcl";
printf("installing %s-%s\n",impl,version);
ensure_directories_exist(impl_path);
printf("cd:%s\n",src);
change_directory(src);
setenv("SBCL_HOME",sbcl_home,1);
setenv("INSTALL_ROOT",install_root,1);
if(system("sh install.sh")==-1) {
ret=0;
}
s(home);
s(impl_path);
s(src);
s(sbcl_home);
s(install_root);
return ret;
#else
#error not implemented.
#endif
}
install_cmds install_full[]={
start,
download,
expand,
configure,
NULL
};
install_cmds install_sbcl_full[]={
start,
download,
expand,
sbcl_make,
sbcl_install,
NULL
};
install_cmds install_sbcl_bin_full[]={
start,
download,
expand,
sbcl_install,
NULL
};
int cmd_install(int argc,char **argv)
{
int ret=1;
if(argc!=0) {
char* impl=q(argv[0]);
char* version=NULL;
if(strcmp(impl,"sbcl-bin")==0) {
cmds=install_sbcl_bin_full;
}else if(strcmp(impl,"sbcl")==0) {
cmds=install_sbcl_full;
}else {
printf("%s is not implemented for install.\n",impl);
exit(EXIT_FAILURE);
}
if(argc==1) {
version=get_default_version(impl);
}else {
version=q(argv[1]);
}
for(;*cmds&&ret;++cmds) {
ret=(*cmds)(impl,version);
}
s(version);
}else {
printf("what would you like to install?\n");
exit(EXIT_FAILURE);
}
return ret;
}

71
src/cmd_run.c Normal file
View file

@ -0,0 +1,71 @@
#include <stdio.h>
#include <stdlib.h>
#include "util.h"
#include "opt.h"
int cmd_run(int argc,char **argv)
{
int ret=1;
char* impl;
char* version;
char* home=homedir();
int pos;
impl=get_opt("impl");
if(impl && (pos=position_char("/",impl))!=-1) {
version=subseq(impl,pos+1,0);
impl=subseq(impl,0,pos);
}else {
version=get_opt("version");
}
if(impl) {
char** arg=NULL;
char* bin=NULL;
int offset=0;
int i;
if(strcmp(impl,"sbcl-bin")==0) {
impl="sbcl";
if(version) {
version=cat(q(version),q("-"),uname_m(),q("-"),uname(),NULL);
}
}
if(strcmp(impl,"sbcl")==0) {
char* impl_path= cat(home,"impls/",impl,"-",version,NULL);
int core_p=1;
bin= cat(impl_path,"/bin/sbcl",NULL);
for(i=0;i<argc;++i) {
if(strcmp(argv[i],"--core")==0) {
core_p=0;
break;
}
}
arg=malloc(sizeof(char*)*(offset+2+argc));
arg[0]=bin;
if(core_p) {
offset=2;
arg[1]="--core";
arg[2]=cat(impl_path,"/lib/sbcl/sbcl.core",NULL);
}
s(impl_path);
}else if (strcmp(impl,"native")==0) {
bin= which(version);
if(strcmp(bin,"")!=0) {
arg=malloc(sizeof(char*)*(offset+2+argc));
arg[0]=bin;
}else {
printf("can't find %s.\n",version);
exit(EXIT_FAILURE);
}
}
for(i=0;i<argc;++i) {
arg[i+1+offset]=argv[i];
}
arg[i+1+offset]=NULL;
execvp(bin,arg);
}else {
printf("impl doesn't specified stop");
}
s(home);
return ret;
}

10
src/cmd_version.c Normal file
View file

@ -0,0 +1,10 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
int cmd_version(int argc,char **argv)
{
printf("%s\n",PACKAGE_STRING);
return 0;
}

51
src/download.c Normal file
View file

@ -0,0 +1,51 @@
#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>
static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
int written = fwrite(ptr, size, nmemb, (FILE *)stream);
return written;
}
extern char* homedir(void);
extern int ensure_directories_exist (char* path);
int download_simple (char* uri,char* path,int verbose)
{
CURL *curl;
CURLcode res;
FILE *bodyfile;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, uri);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
bodyfile = fopen(path,"wb");
if (bodyfile == NULL) {
curl_easy_cleanup(curl);
return -1;
}
curl_easy_setopt(curl,CURLOPT_WRITEDATA,bodyfile);
res = curl_easy_perform(curl);
if(res != CURLE_OK && verbose) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
curl_easy_cleanup(curl);
}
fclose(bodyfile);
if(res != CURLE_OK) {
return -2;
}else {
return 0;
}
}
int cmd_download (int argc,char **argv) {
if(argc>=2) {
return download_simple(argv[0],argv[1],1);
}
return 0;
}

92
src/lsp.c Normal file
View file

@ -0,0 +1,92 @@
#include <stdio.h>
#include <string.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "opt.h"
#include "util.h"
char** argv_orig;
int argc_orig;
struct opts* global_opt;
struct opts* local_opt=NULL;
extern int cmd_install(int argc,char **argv);
extern int cmd_download(int argc,char **argv);
extern int cmd_tar(int argc,char **argv);
extern int cmd_version(int argc,char **argv);
extern int cmd_opt(int argc,char **argv);
extern int cmd_run(int argc,char **argv);
int cmd_notyet(int argc,char **argv)
{
printf("notyet\n");
}
static struct sub_command commands[] = {
{ "help", cmd_notyet},
{ "version", cmd_version},
{ "install", cmd_install},
{ "run",cmd_run},
{ "opt", cmd_opt},
{ "set", cmd_notyet},
{ "tar",cmd_tar},
{ "download",cmd_download},
};
int main (int argc,char **argv) {
char **subargv=NULL;
char *subcmd=NULL;
int i;
int found=0;
struct sub_command* j;
argv_orig=argv;
argc_orig=argc;
char* path=s_cat(homedir(),q("config"),NULL);
global_opt=load_opts(path);
s(path);
if(argc==1) {
subcmd="help";
subargv=NULL;
argc=0;
} else {
argc--;
argv++;
while(argc>0 && argv[0][0]=='-') {
struct opts* opt=local_opt;
struct opts** opts=&opt;
if(argv[0][1]!='-' && argv[0][1]!='\0' && argc>1 && argv[1][0]!='-') {
set_opt(opts, &argv[0][1],(char*)argv[1],0);
argc--;
argv++;
}else{
int index=1;
if(argv[0][1]=='-') ++index;
set_opt(opts, &argv[0][index],(char*)"1",0);
}
local_opt=*opts;
argc--;
argv++;
}
}
if(argc>0) {
subcmd=argv[0];
subargv=&argv[1];
argc--;
for(i=0;i<sizeof(commands)/sizeof(struct sub_command);i++) {
j = &commands[i];
if(strcmp(subcmd,j->name)==0) {
found=1;
j->call(argc,subargv);
break;
}
}
if(!found) {
printf("action %s not found\n",subcmd);
}
}
free_opts(global_opt);
}
/* ./lsp tar -xvf ~/.lsp/archives/sbcl-1.2.1.tar.bz2 */

210
src/opt.c Normal file
View file

@ -0,0 +1,210 @@
#include <stdio.h>
#include <stdlib.h>
#include "opt.h"
#include "util.h"
void free_opts(struct opts* opt)
{
void* tmp;
while(opt) {
if(opt->value) {
free((void*)opt->value);
opt->value=NULL;
}
if(opt->name) {
free((void*)opt->name);
opt->name=NULL;
}
tmp=opt->next;
opt->next=NULL;
tmp=opt;
opt=opt->next;
free(tmp);
}
}
void print_opts(struct opts* opt)
{
void* tmp;
char* typestr;
while(opt) {
switch(opt->type) {
case OPT_INT:
typestr="int";
break;
case OPT_STRING:
typestr="string";
break;
case OPT_BOOL:
typestr="bool";
break;
default:
typestr="unknown";
}
printf("%s=%s[%s]\n",opt->name,opt->value,typestr);
opt=opt->next;
}
}
struct opts* load_opts(const char* path) {
FILE* fp;
char buf[1024];
struct opts opt;
struct opts *cur=&opt;
if((fp=fopen(path,"r"))==NULL) {
return NULL;
}
while(fgets(buf,1024,fp) !=NULL) {
int i,mode,last;
char* str;
cur->next=(struct opts*)malloc(sizeof(struct opts));
cur=cur->next;
cur->type=OPT_VOID;
cur->value=NULL;
cur->name=NULL;
cur->next=NULL;
for(i=0,mode=0,last=0;i<1024&&buf[i]!='\0';++i) {
if(buf[i]=='\t'||buf[i]=='\n') {
switch (mode++) {
case 0:
cur->name=subseq(buf,last,i);
break;
case 1:
cur->type=buf[i-1]-'0';
break;
case 2:
cur->value=subseq(buf,last,i);
break;
}
last=i+1;
}
}
}
fclose (fp);
return opt.next;
}
int save_opts(const char* path,struct opts* opt) {
FILE* fp;
void* tmp;
if((fp=fopen(path,"w"))==NULL) {
return 0;
}
while(opt) {
fprintf(fp,"%s\t%d\t%s\n",opt->name,opt->type,opt->value);
opt=opt->next;
}
fclose(fp);
return 1;
}
int set_opt(struct opts** opts,const char* name,char* value,int type)
{
int found=0;
struct opts* opt=*opts;
while(opt) {
if(strcmp(opt->name,name)==0) {
found=1;
s((char*)opt->value);
opt->value=remove_char("\n\t",value);
if(type!=0) {
opt->type=type;
}
}
opt=opt->next;
}
if(!found) {
opt=(struct opts*)malloc(sizeof(struct opts));
opt->next=*opts;
opt->type=type;
opt->name=(const char*)remove_char("\n\t",(char*)name);
opt->value=remove_char("\n\t",value);
*opts=opt;
}
return 1;
}
int get_opt_type(struct opts* opt,const char* name)
{
while(opt) {
if(strcmp(opt->name,name)==0) {
return opt->type;
}
opt=opt->next;
}
return 0;
}
char* _get_opt(struct opts* opt,const char* name)
{
while(opt) {
if(strcmp(opt->name,name)==0) {
return (char*)opt->value;
}
opt=opt->next;
}
return NULL;
}
char* get_opt(const char* name)
{
char* ret=NULL;
ret=_get_opt(local_opt,name);
if(!ret) {
ret=_get_opt(global_opt,name);
}
return ret;
}
int unset_opt(struct opts** opts,const char* name)
{
struct opts *opt=*opts;
struct opts dummy;
struct opts *before=&dummy;
before->next=opt;
while(opt) {
if(strcmp(opt->name,name)==0) {
before->next=opt->next;
opt->next=NULL;
free_opts(opt);
opt=before;
}
before=opt;
opt=opt->next;
}
*opts=dummy.next;
return 1;
}
int set_opts_int(struct opts* opts,const char* name,int value) {
}
int cmd_opt(int argc, const char **argv)
{
char* home=homedir();
char* path=cat(home,"config",NULL);
struct opts* opt=global_opt;
struct opts** opts=&opt;
if(argc==0) {
printf("local:\n");
print_opts(local_opt);
printf("global:\n");
print_opts(opt);
}else if(strcmp(argv[0],"set")==0) {
if(argc>=3) {
set_opt(opts, argv[1],(char*)argv[2],0);
save_opts(path,opt);
}
}else if(strcmp(argv[0],"unset")==0) {
if(argc>=2) {
unset_opt(opts, argv[1]);
save_opts(path,opt);
}
}
s(home);
s(path);
}

29
src/opt.h Normal file
View file

@ -0,0 +1,29 @@
#ifndef __OPT_H__
#define __OPT_H__
typedef int (*sub_command_fnc)(int argc,char **argv);
struct opts
{
const char* name;
int type;
const char* value;
struct opts* next;
};
enum opt_type {
OPT_VOID,
OPT_INT,
OPT_STRING,
OPT_BOOL
};
struct sub_command
{
const char* name;
sub_command_fnc call;
};
extern struct opts* global_opt;
extern struct opts* local_opt;
struct opts* load_opts(const char* path);
char* get_opt(const char* name);
#endif

337
src/util.c Normal file
View file

@ -0,0 +1,337 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef _WIN32
#include <pwd.h>
#include <unistd.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include <stdarg.h>
char* q(const char* orig) {
char* ret= (char*)malloc(strlen(orig)+1);
strcpy(ret,orig);
return ret;
}
void s(char* f) {
free(f);
}
char* s_cat2(char* a,char* b) {
char* ret= (char*)malloc(strlen(a)+strlen(b)+1);
strcpy(ret,a);
strcat(ret,b);
s(a);
s(b);
return ret;
}
char* s_cat(char* first,...)
{
char* ret=first;
char* i;
va_list list;
va_start(list,first);
for(i=va_arg( list , char*);i!=NULL;i=va_arg( list , char*)) {
ret=s_cat2(ret,i);
}
va_end(list);
return ret;
}
char* cat(char* first,...)
{
char* ret=q(first);
char* i;
va_list list;
va_start(list,first);
for(i=va_arg( list , char*);i!=NULL;i=va_arg( list , char*)) {
ret=s_cat2(ret,q(i));
}
va_end(list);
return ret;
}
char* subseq(char* base,int beg,int end)
{
int len=-1;
int i;
char* ret;
if(0>beg) {
if(0>len) {
len=strlen(base);
}
beg=len+beg;
}
if(0>=end) {
if(0>len) {
len=strlen(base);
}
end=len+end;
}
if(end<=beg)
return NULL;
ret=malloc(end-beg+1);
for(i=0;i<end-beg;++i) {
ret[i]=base[i+beg];
}
ret[i]='\0';
return ret;
}
char* remove_char(char* items,char* orig)
{
int i,j,k;
int found=0;
char* ret;
/* count removed*/
for(j=0;orig[j]!='\0';++j) {
for(i=0;items[i]!='\0';++i) {
if(items[i]==orig[j]){
++found;
break;
}
}
}
ret=malloc(j+1-found);
for(j=0,k=0;orig[j]!='\0';++j,++k) {
for(i=0;items[i]!='\0';++i) {
ret[k]=orig[j];
if(items[i]==orig[j]){
--k;
break;
}
}
}
ret[k]='\0';
return ret;
}
int position_char(char* items,char* seq) {
int i,j;
for(i=0;seq[i]!='\0';++i) {
for(j=0;items[j]!='\0';++j) {
if(seq[i]==items[j])
return i;
}
}
return -1;
}
char* substitute_char(char new,char old,char* seq) {
int i;
for(i=0;seq[i]!='\0';++i) {
if(seq[i]==old)
seq[i]=new;
}
return seq;
}
char* upcase(char* orig) {
int i;
for(i=0;orig[i]!='\0';++i) {
if('a'<=orig[i] && orig[i]<='z')
orig[i]=orig[i]-'a'+'A';
}
return orig;
}
char* downcase(char* orig) {
int i;
for(i=0;orig[i]!='\0';++i) {
if('A'<=orig[i] && orig[i]<='Z')
orig[i]=orig[i]-'A'+'a';
}
return orig;
}
char* append_trail_slash(char* str) {
char* ret;
if(str[strlen(str)-1]!='/') {
ret=s_cat2(q(str),q("/"));
}else {
ret=q(str);
}
s(str);
return ret;
}
char* homedir(void) {
#ifdef _WIN32
return q("/dummy");
#else
char *c;
char *postfix="_HOME";
struct passwd * pwd;
char *env=NULL;
int i;
c=s_cat2(upcase(q(PACKAGE)),q(postfix));
env=getenv(c);
s(c);
if(env) {
return append_trail_slash(q(env));
}
pwd= getpwnam(getenv("USER"));
if(pwd) {
c=q(pwd->pw_dir);
}else {
/* error? */
return NULL;
}
c=append_trail_slash(c);
return s_cat(c,q("."),q(PACKAGE),q("/"),NULL);
#endif
}
char* pathname_directory(char* path) {
int i;
char* ret;
for(i=strlen(path)-1;i>=0&&path[i]!='/';--i);
ret=append_trail_slash(subseq(path,0,i));
s(path);
return ret;
}
char* ensure_directories_exist (char* path) {
int len = strlen(path);
if(len) {
for(--len;(path[len]!='/'||len==-1);--len);
path=subseq(path,0,len+1);
}
#ifndef _WIN32
char* cmd=s_cat2(q("mkdir -p "),path);
#else
char* cmd=q("");
#endif
if(system(cmd)==-1) {
printf("failed:%s\n",cmd);
return NULL;
};
s(cmd);
return path;
}
int directory_exist_p (char* path) {
#ifdef HAVE_SYS_STAT_H
struct stat sb;
int ret=0;
if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
ret=1;
}
return ret;
#else
# error not imprement directory_exist_p
#endif
}
int change_directory(const char* path) {
#ifndef _WIN32
return chdir(path);
#else
return _chdir(path);
#endif
}
int delete_directory(char* pathspec,int recursive) {
#ifndef _WIN32
char* cmd;
int ret;
if(recursive) {
cmd=s_cat2(q("rm -rf "),q(pathspec));
}else {
cmd=s_cat2(q("rmdir "),q(pathspec));
}
ret=system(cmd);
s(cmd);
if(ret==-1) {
return 0;
}else {
return 1;
}
#else
#error not implemented delete_directory
#endif
}
int delete_file(char* pathspec) {
#ifndef _WIN32
char* cmd;
int ret;
cmd=s_cat2(q("rm -f "),q(pathspec));
ret=system(cmd);
s(cmd);
if(ret==-1) {
return 0;
}else {
return 1;
}
#else
#error not implemented delete_file
#endif
}
void touch(char* path) {
#ifndef _WIN32
char* cmd=s_cat2(q("touch "),q(path));
#else
char* cmd=q("");
#endif
if(system(cmd)==-1){
};
s(cmd);
}
char* system_(char* cmd) {
#ifndef _WIN32
FILE *fp;
char buf[256];
char* s=q("");
if((fp=popen(cmd,"r")) ==NULL) {
printf("Error:%s\n",cmd);
exit(EXIT_FAILURE);
}
while(fgets(buf,256,fp) !=NULL) {
s=s_cat2(s,q(buf));
}
(void)pclose(fp);
return s;
#else
#endif
}
char* uname(void) {
char *p=system_("uname");
char *p2;
p2=remove_char("\r\n",p);
s(p);
return downcase(p2);
}
char* uname_m(void) {
char *p=system_("uname -m");
char *p2;
p2=remove_char("\r\n",p);
s(p);
return substitute_char('-','_',p2);
}
char* which(char* cmd) {
char* which_cmd=cat("command -v \"",cmd,"\"",NULL);
char* p=system_(which_cmd);
char* p2=remove_char("\r\n",p);
s(p),s(which_cmd);
return p2;
}

24
src/util.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef __UTIL_H__
#define __UTIL_H__
char* q(const char* orig);
void s(char* f);
char* s_cat2(char* a,char* b);
char* s_cat(char* first,...);
char* cat(char* first,...);
char* subseq(char* base,int beg,int end);
char* remove_char(char* items,char* orig);
int position_char(char* items,char* seq);
char* upcase(char* orig);
char* homedir(void);
char* pathname_directory (char* path);
char* ensure_directories_exist (char* path);
int directory_exist_p (char* path);
int change_directory(const char* path);
int delete_directory(char* pathspec,int recursive);
int delete_file(char* pathspec);
void touch(char* path);
char* system_(char* cmd);
char* uname(void);
char* uname_m(void);
char* which(char* cmd);
#endif