Commit ee8190f2 authored by monty@narttu.mysql.fi's avatar monty@narttu.mysql.fi

Merge

parents 8cf4e729 f4e21128
...@@ -22,7 +22,7 @@ LIBS = @CLIENT_LIBS@ ...@@ -22,7 +22,7 @@ LIBS = @CLIENT_LIBS@
LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysql/libmysqlclient.la LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysql/libmysqlclient.la
bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \ bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \
mysqldump mysqlimport mysqltest mysqlbinlog mysqlmanagerc mysqlmanager-pwgen mysqldump mysqlimport mysqltest mysqlbinlog mysqlmanagerc mysqlmanager-pwgen
noinst_PROGRAMS = insert_test select_test thread_test ssl_test noinst_PROGRAMS = insert_test select_test thread_test
noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \ noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \
client_priv.h client_priv.h
mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc
...@@ -34,8 +34,6 @@ mysqlcheck_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) ...@@ -34,8 +34,6 @@ mysqlcheck_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
mysqlshow_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) mysqlshow_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
mysqldump_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) mysqldump_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
mysqlimport_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) mysqlimport_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
insert_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
select_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
mysqltest_SOURCES= mysqltest.c mysqltest_SOURCES= mysqltest.c
mysqltest_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) mysqltest_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
mysqlbinlog_SOURCES = mysqlbinlog.cc mysqlbinlog_SOURCES = mysqlbinlog.cc
...@@ -53,8 +51,5 @@ link_sources: ...@@ -53,8 +51,5 @@ link_sources:
@LN_CP_F@ $(top_srcdir)/sql/$$f $(srcdir)/$$f; \ @LN_CP_F@ $(top_srcdir)/sql/$$f $(srcdir)/$$f; \
done; done;
thread_test.o: thread_test.c
$(COMPILE) -c @MT_INCLUDES@ $(INCLUDES) $<
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%
/* Copyright (C) 2000 MySQL AB
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "my_my_global.h"
static void spawn_stern_thread(pthread_t *t);
static int act_goofy(void);
static void *be_stern(void *);
static struct {
pthread_mutex_t lock;
pthread_cond_t cond;
int msg;
} comm = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0 };
int
main(void)
{
pthread_t t;
spawn_stern_thread(&t);
while (act_goofy() != 0)
/* do nothing */;
pthread_exit(NULL);
/* notreached */
return EXIT_SUCCESS;
}
static void spawn_stern_thread(pthread_t *t)
{
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (pthread_create(t, &attr, be_stern, NULL) != 0)
exit(EXIT_FAILURE);
pthread_attr_destroy(&attr);
}
static int act_goofy(void)
{
int ret;
char buf[30];
fputs("Are you ready to act goofy (Y/n)? ", stdout); fflush(stdout);
fgets(buf, sizeof(buf), stdin);
pthread_mutex_lock(&comm.lock);
if (buf[0] == 'y' || buf[0] == '\n') {
fputs("** Waawlwalkwwwaa!!\n", stdout); fflush(stdout);
++comm.msg;
ret = 1;
}
else {
fputs("OK, I hate you. Let me go.\n", stdout); fflush(stdout);
comm.msg = -1;
ret = 0;
}
pthread_mutex_unlock(&comm.lock);
pthread_cond_signal(&comm.cond);
return ret;
}
static void *be_stern(void *v __attribute__((unused)))
{
int msg;
for (;;) {
pthread_mutex_lock(&comm.lock);
while (comm.msg == 0)
pthread_cond_wait(&comm.cond, &comm.lock);
msg = comm.msg;
comm.msg = 0;
pthread_mutex_unlock(&comm.lock);
if (msg < 0)
break; /* the goofy one learned a lesson! */
fputs("I HAVE TO BE STERN WITH YOU!\n", stderr);
fprintf(stderr, "I should give you %d lashes.\n", msg);
sleep(msg);
}
fputs("You are NOTHING!\n", stderr);
return NULL;
}
...@@ -18,7 +18,7 @@ INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include ...@@ -18,7 +18,7 @@ INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include
LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \ LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \
../dbug/libdbug.a ../strings/libmystrings.a ../dbug/libdbug.a ../strings/libmystrings.a
bin_PROGRAMS = replace comp_err perror resolveip my_print_defaults \ bin_PROGRAMS = replace comp_err perror resolveip my_print_defaults \
resolve_stack_dump mysql_install mysql_waitpid resolve_stack_dump mysql_waitpid
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
/* Install or upgrade MySQL server. By Sasha Pachev <sasha@mysql.com>
*/
#define INSTALL_VERSION "1.2"
#define DONT_USE_RAID
#include <my_global.h>
#include <m_ctype.h>
#include <my_sys.h>
#include <m_string.h>
#include <mysql_version.h>
#include <errno.h>
#include <my_getopt.h>
#define ANSWERS_CHUNCK 32
int have_gui=0;
static struct my_option my_long_options[] =
{
{"help", '?', "Display this help and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Output version information and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
/* For now, not much exciting here, but we'll add more once
we add GUI support
*/
typedef struct
{
FILE* out;
FILE* in;
const char* question;
int default_ind;
DYNAMIC_ARRAY answers;
} QUESTION_WIDGET;
static void usage();
static void die(const char* fmt, ...);
static void print_version(void);
static char get_answer_char(int ans_ind);
static int ask_user(const char* question,int default_ind, ...);
static void add_answer(QUESTION_WIDGET* w, const char* ans);
static void display_question(QUESTION_WIDGET* w);
static int init_question_widget(QUESTION_WIDGET* w, const char* question,
int default_ind);
static void end_question_widget(QUESTION_WIDGET* w);
static int get_answer(QUESTION_WIDGET* w);
static char answer_from_char(char c);
static void invalid_answer(QUESTION_WIDGET* w);
enum {IMODE_STANDARD=0,IMODE_CUSTOM,IMODE_UPGRAGE} install_mode
= IMODE_STANDARD;
static char get_answer_char(int ans_ind)
{
return 'a' + ans_ind;
}
static void invalid_answer(QUESTION_WIDGET* w)
{
if (!have_gui)
{
fprintf(w->out, "ERROR: invalid answer, try again...\a\n");
}
}
static char answer_from_char(char c)
{
return c - 'a';
}
static void die(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
fprintf(stderr, "%s: ", my_progname);
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
va_end(args);
exit(1);
}
static void display_question(QUESTION_WIDGET* w)
{
if (!have_gui)
{
uint i,num_answers=w->answers.elements;
DYNAMIC_ARRAY* answers = &w->answers;
fprintf(w->out,"\n%s\n\n",w->question);
for (i=0; i<num_answers; i++)
{
char* ans;
get_dynamic(answers,(gptr)&ans,i);
fprintf(w->out,"%c - %s\n",get_answer_char(i),ans);
}
fprintf(w->out,"q - Abort Install/Upgrade\n\n");
}
}
static void add_answer(QUESTION_WIDGET* w, const char* ans)
{
insert_dynamic(&w->answers,(gptr)&ans);
}
static int init_question_widget(QUESTION_WIDGET* w, const char* question,
int default_ind)
{
if (have_gui)
{
w->in = w->out = 0;
}
else
{
w->out = stdout;
w->in = stdin;
}
w->question = question;
w->default_ind = default_ind;
if (my_init_dynamic_array(&w->answers,sizeof(char*),
ANSWERS_CHUNCK,ANSWERS_CHUNCK))
die("Out of memory");
return 0;
}
static void end_question_widget(QUESTION_WIDGET* w)
{
delete_dynamic(&w->answers);
}
static int get_answer(QUESTION_WIDGET* w)
{
if (!have_gui)
{
char buf[32];
int ind;
char c;
if (!fgets(buf,sizeof(buf),w->in))
die("Failed fgets on input stream");
switch ((c=my_tolower(&my_charset_latin1,*buf)))
{
case '\n':
return w->default_ind;
case 'q':
die("Install/Upgrade aborted");
default:
ind = answer_from_char(c);
if (ind >= 0 && ind < (int)w->answers.elements)
return ind;
}
}
return -1;
}
static int ask_user(const char* question,int default_ind, ...)
{
va_list args;
char* opt;
QUESTION_WIDGET w;
int ans;
va_start(args,default_ind);
init_question_widget(&w,question,default_ind);
for (;(opt=va_arg(args,char*));)
{
add_answer(&w,opt);
}
for (;;)
{
display_question(&w);
if ((ans = get_answer(&w)) >= 0)
break;
invalid_answer(&w);
}
end_question_widget(&w);
va_end(args);
return ans;
}
static my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument __attribute__((unused)))
{
switch(optid) {
case 'V':
print_version();
exit(0);
case '?':
usage();
exit(0);
}
return 0;
}
static int parse_args(int argc, char **argv)
{
int ho_error;
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
exit(ho_error);
return 0;
}
static void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,INSTALL_VERSION,
MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
}
static void usage()
{
print_version();
printf("MySQL AB, by Sasha Pachev\n");
printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
printf("Install or upgrade MySQL server.\n\n");
printf("Usage: %s [OPTIONS] \n", my_progname);
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
int main(int argc, char** argv)
{
MY_INIT(argv[0]);
parse_args(argc,argv);
install_mode = ask_user("Please select install/upgrade mode",
install_mode, "Standard Install",
"Custom Install", "Upgrade",0);
printf("mode=%d\n", install_mode);
return 0;
}
// -----------------------------------------------------------------------------
// CorbaDS Module - Implement Kernel functionality in korbit
// -----------------------------------------------------------------------------
//
// Main source of information:
// http://www.cse.unsw.edu.au/~neilb/oss/linux-commentary/vfs.html
//
module CorbaFS {
struct dirent
{
long inode; // inode number
string name; // file name (null-terminated)
};
typedef sequence<dirent> DirEntSeq;
typedef sequence<octet> Buffer;
interface Inode {
void getStatus(out unsigned short mode, out unsigned long uid, out unsigned long gid,
out unsigned long size, out unsigned long inodeNum, out unsigned short numLinks,
out long atime, out long mtime, out long ctime);
void readpage(out Buffer buffer, in long size, in long offset);
void release();
};
interface FileSystem {
Inode getInode(in string path);
// DirectoryInode getStatus implementation must have S_IFDIR in the S_IFMT
// field of the mode value.
DirEntSeq readdir(in string path);
// SymlinkInode getStatus implementation must have S_IFLNK in the S_IFMT
// field of the mode value.
string readlink(in string filename);
};
};
# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#called from the top level Makefile
CFLAGS = $(ORBIT_CFLAGS) -g
LFLAGS = $(ORBIT_LIBS)
orbit_idl = @orbit_idl@
orbit_includes = @orbit_includes@
orbit_libs = @orbit_libs@
DISTCLEANFILES = CorbaFS-common.* CorbaFS-stubs.* CorbaFS-skels.* CorbaFS.h
MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include \
-I$(top_srcdir)/regex $(orbit_includes)
WRAPLIBS= @WRAPLIBS@
libexec_PROGRAMS = mysqlcorbafsd
noinst_PROGRAMS =mysqlfs_test
LDADD = ../libmysql/libmysqlclient.la $(orbit_libs)
mysqlcorbafsd_LDADD = $(LDADD) $(CXXLDFLAGS)
noinst_HEADERS =
mysqlfs_test_SOURCES = mysqlcorbafs_test.c CorbaFS-common.c CorbaFS-stubs.c libmysqlfs.c
mysqlcorbafsd_SOURCES = mysqlcorbafs.c CorbaFS-skels.c database.c CorbaFS-common.c libmysqlfs.c
DEFS = -DMYSQL_SERVER \
-DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
-DDATADIR="\"$(MYSQLDATAdir)\"" \
-DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
@DEFS@
# Don't put lex_hash.h in BUILT_SOURCES as this will give infinite recursion
BUILT_SOURCES = CorbaFS-common.c CorbaFS-stubs.c CorbaFS-skels.c CorbaFS.h
EXTRA_DIST = $(BUILT_SOURCES)
#YFLAGS = -d
OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\
__math.h time.h __time.h unistd.h __unistd.h types.h \
xtypes.h ac-types.h posix.h string.h __string.h \
errno.h socket.h inet.h dirent.h netdb.h \
cleanup.h cond.h debug_out.h fd.h kernel.h mutex.h \
prio_queue.h pthread_attr.h pthread_once.h queue.h\
sleep.h specific.h version.h pwd.h timers.h uio.h \
cdefs.h machdep.h signal.h __signal.h util.h lex.h \
wait.h
link_sources:
rm -f mini_client_errors.c
@LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c
# Don't update the files from bitkeeper
%::SCCS/s.%
idltargets : CorbaFS.idl
$(ORBIT_IDL) CorbaFS.idl
$(orbit_idl) CorbaFS.idl
# individual rules
CorbaFS-stubs.c : CorbaFS.idl
$(orbit_idl) CorbaFS.idl
CorbaFS-common.c : CorbaFS.idl
$(orbit_idl) CorbaFS.idl
CorbaFS-skels.c : CorbaFS.idl
$(orbit_idl) CorbaFS.idl
#CorbaFS-client.c : CorbaFS.h
#CorbaFS-server.c : CorbaFS.h
CorbaFS.h : CorbaFS.idl
$(orbit_idl) CorbaFS.idl
MySQL Filesystem
Tnu Samuel - tonu@mysql.com
Some additional information is available on http://no.spam.ee/~tonu/mysqlfs.html
WARNING: Experimental code and known to crash computer.
Instructions, how to get this stuff working:
1. Make sure you have ORBit, includeing development libraries installed. They should be version 0.5.3 or later.
- I am lazy man and use default ones included with my RedHat:
[root@localhost /root]# rpm -qa | grep ORBit
ORBit-0.5.3-2
ORBit-devel-0.5.3-2
[root@localhost /root]#
2. Prepare kernel to include korbit:
- Get Linux 2.4.1 kernel source. (very possibly this patch works on 2.4.0 without modifications too)
- unpack it
- apply patch named "korbit-kernel-2.4.1-patch" on it.
- make menuconfig
- In section "Networking options":
...
[*] Kernel ORB (EXPERIMENTAL)
...
<M> CORBA User-space FileSystem (EXPERIMENTAL)
...
- make dep ; make bzlilo ; make modules ; make modules_install
- reboot
- Execute: insmod /lib/modules/$(uname -r)/kernel/net/korbit/modules/CorbaFS/client/corba-corbafs-client.o
You should see "gethostname() = localhost". Look at known bug 3 in the end of this doc.
3. Make sure MySQL server is working on your system
- On my RedHat 7.0 I execute "/etc/init.d/mysqld start"
4. Prepare MySQL FS daemon
- Get MySQL 4.0 from repository OR get MySQL FS source from http://no.spam.ee/~tonu/mysqlfs.html
- unpack it. In MySQL 4.0 source this is located in directory named "fs". cd into it.
- make
- Execute command "./RunServer"
5. mount MySQL server to disk tree
- Execute command "mkdir /mnt/mysql"
- Execute command "mount -t corbafs -o `cat /tmp/mysqlcorbafs.ior` none /mnt/mysql/"
- Check you SQL server content by executing "ls -la /mnt/mysql/"
Known bugs:
1. User bugs. fix user ;)
2. MySQL FS daemon will crash or will be stopped when cobrafs is mounted, then there is no way
to unmount disks anymore. This is korbit business to handle such cases and I had no time to dig
into korbit code.
3. host name returned by gethostname() should be "localhost" or korbit will crash. Also "localhost"
must be first string after 127.0.0.1 in /etc/hosts
.libs/mysqlcorbafsd -ORBIIOPUSock=0 -ORBIIOPIPv4=1 --debug='d:t:o,~/mysqlfsd.trace' $*
#.libs/mysqlcorbafsd -ORBIIOPUSock=0 -ORBIIOPIPv4=1 $*
/* Copyright (C) 2000 db AB & db Finland AB & TCX DataKonsult AB
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Database functions
*
* Using these functions we emulate filesystem behaviour on top of SQL
* database.
* Written by Tnu Samuel <tonu@please.do.not.remove.this.spam.ee>
*
* FIXME:
* - Direct handling of database handlers without SQL parsing overhead
* - connection pool
* - configurable function name/file name mappings
*/
#include "libmysqlfs.h"
#include "mysqlcorbafs.h"
#include <unistd.h>
#include <string.h>
#include <my_sys.h>
DYNAMIC_ARRAY field_array;
/*
* ** dbConnect -- connects to the host and selects DB.
* ** Also checks whether the tablename is a valid table name.
* */
int db_connect(char *host, char *user,char *passwd)
{
DBUG_ENTER("db_connect");
DBUG_PRINT("enter",("host: '%s', user: '%s', passwd: '%s'", host, user, passwd));
if (verbose)
{
fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost");
}
mysql_init(&connection);
if (opt_compress)
mysql_options(&connection,MYSQL_OPT_COMPRESS,NullS);
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
mysql_ssl_set(&connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath);
#endif
if (!(sock= mysql_real_connect(&connection,host,user,passwd,
NULL,opt_mysql_port,opt_mysql_unix_port,0)))
{
DBerror(&connection, "when trying to connect");
DBUG_RETURN(1);
}
DBUG_RETURN(0);
} /* dbConnect */
/*
* ** dbDisconnect -- disconnects from the host.
* */
void db_disconnect(char *host)
{
DBUG_ENTER("db_disconnect");
DBUG_PRINT("enter",("host: '%s'", host));
if (verbose)
fprintf(stderr, "# Disconnecting from %s...\n", host ? host : "localhost");
mysql_close(sock);
DBUG_VOID_RETURN;
} /* dbDisconnect */
#define OUTPUT(x) strcpy(buffptr,x); buffptr+=strlen(x);
#define OUTPUT_TOP(x) strcpy(topptr,x); topptr+=strlen(x);
#define OUTPUT_MIDDLE(x) strcpy(midptr,x); midptr+=strlen(x);
#define OUTPUT_BOTTOM(x) strcpy(botptr,x); botptr+=strlen(x);
#define OUTPUT_HEADER(x) strcpy(hdrptr,x); hdrptr+=strlen(x);
void db_show_result(MYSQL* sock, char *b, struct format *f)
{
MYSQL_ROW row;
MYSQL_RES *result;
MYSQL_FIELD *field;
char *buffptr;
char topseparator[BUFLEN]="";
char middleseparator[BUFLEN]="";
char bottomseparator[BUFLEN]="";
char header[BUFLEN]="";
char *topptr=topseparator;
char *midptr=middleseparator;
char *botptr=bottomseparator;
char *hdrptr=header;
uint i,count, length;
DBUG_ENTER("db_show_result");
DBUG_PRINT("enter",("b: '%s', f '%x'", b, f));
result=mysql_store_result(sock);
buffptr=b;
OUTPUT(f->tablestart)
OUTPUT_TOP(f->leftuppercorner);
OUTPUT_MIDDLE(f->leftcross);
OUTPUT_BOTTOM(f->leftdowncorner);
OUTPUT_HEADER(f->headerrowstart);
count=mysql_num_fields(result);
// while ((field = mysql_fetch_field(result)))
for(i=0 ; i < count ; ++i)
{
field = mysql_fetch_field(result);
length=(uint) strlen(field->name);
OUTPUT_HEADER(f->headercellstart);
length=max(length,field->max_length);
if (length < 4 && !IS_NOT_NULL(field->flags))
length=4; // Room for "NULL"
field->max_length=length;
memset(topptr,'=',field->max_length);
memset(midptr,'-',field->max_length);
memset(botptr,'=',field->max_length);
sprintf(hdrptr,"%-*s",field->max_length,field->name);
//num_flag[off]= IS_NUM(field->type);
topptr+=field->max_length;
midptr+=field->max_length;
botptr+=field->max_length;
hdrptr+=field->max_length;
if(i<count-1) {
OUTPUT_TOP(f->topcross);
OUTPUT_MIDDLE(f->middlecross);
OUTPUT_BOTTOM(f->bottomcross);
OUTPUT_HEADER(f->headercellseparator);
}
}
OUTPUT_TOP(f->rightuppercorner);
OUTPUT_MIDDLE(f->rightcross);
OUTPUT_BOTTOM(f->rightdowncorner);
OUTPUT_HEADER(f->headercellend);
OUTPUT_HEADER(f->headerrowend);
OUTPUT(topseparator);
OUTPUT(header);
OUTPUT(middleseparator);
while(row=mysql_fetch_row(result)) {
mysql_field_seek(result,0);
OUTPUT(f->contentrowstart);
for(i=0 ; i < mysql_field_count(sock); ++i) {
field = mysql_fetch_field(result);
OUTPUT(f->contentcellstart);
sprintf(buffptr,"%-*s",field->max_length,row[i]);
buffptr+=field->max_length;
if(i==mysql_field_count(sock))
{
OUTPUT(f->contentcellend);
} else {
OUTPUT(f->contentcellseparator);
}
}
OUTPUT(f->contentrowend);
}
OUTPUT(bottomseparator);
OUTPUT(f->tableend);
mysql_free_result(result);
DBUG_VOID_RETURN;
}
int db_function(char *b,const char *server, const char *database,const char *table,const char *field, const char *value, const char* path, struct func_st *function)
{
char buff[BUFLEN];
int i;
DBUG_ENTER("db_function");
DBUG_PRINT("enter",("buffer: '%s', database: '%s', table: '%s', field: '%s', path: '%s'", b, database, table, field,path));
if(*database) {
if (mysql_select_db(sock,database))
{
printf("error when changing database to'%s'\n",database);
DBUG_RETURN(-1);
}
}
sprintf(buff,"%s",function->function);
search_and_replace("$database",database,buff);
search_and_replace("$table",table,buff);
search_and_replace("$field",field,buff);
search_and_replace("$value",value,buff);
DBUG_PRINT("info",("path: '%s'",path));
DBUG_PRINT("info",("sum: '%d'",(database[0] ? strlen(database)+1 : 0) +(table[0] ? strlen(table)+1 : 0) +(field[0] ? strlen(field)+1 : 0) +(value[0] ? strlen(value)+1 : 0) +1));
search_and_replace("$*",path+
(server[0] ? strlen(server)+1 : 0) +
(database[0] ? strlen(database)+1 : 0) +
(table[0] ? strlen(table)+1 : 0) +
(field[0] ? strlen(field)+1 : 0) +
(value[0] ? strlen(value)+1 : 0) +
function->length +
1,buff);
DBUG_PRINT("info",("Executing constructed function query: '%s'", buff));
if (mysql_query(sock, buff))
{
printf("error when executing '%s'\n",buff);
sprintf(b,"ERROR %d: %s",mysql_error(sock),mysql_error(sock));
DBUG_VOID_RETURN;
}
db_show_result(sock, b, &Human);
DBUG_PRINT("info",("Returning: %s", b));
DBUG_RETURN(1);
}
int db_show_field(char *b,const char *database,const char *table, const char *field,const char *value, const char *param)
{
MYSQL_RES *result;
MYSQL_ROW row;
char buff[BUFLEN];
int i=0;
my_string *ptr;
DBUG_ENTER("db_show_field");
DBUG_PRINT("enter",("buffer: '%s', database: '%s', table: '%s', field: '%s' value: '%s'", b, database, table, field, value));
/* We cant output fields when one of these variables is missing */
if (!(database[0] && table[0] && field[0]))
DBUG_RETURN(-1);
my_init_dynamic_array(&field_array, sizeof(buff), 4096, 1024);
if (mysql_select_db(sock,database))
{
printf("error when changing database to'%s'\n",database);
delete_dynamic(&field_array);
DBUG_RETURN(-1);
}
if(param) {
sprintf(buff,"%s",param);
} else {
sprintf(buff,"select %s from %s where %s='%s' LIMIT 1",field,table,field,value);
}
if (mysql_query(sock, buff))
{
printf("error when executing '%s'\n",buff);
delete_dynamic(&field_array);
DBUG_RETURN(-1);
}
db_show_result(sock,b,&Human);
/* if(result=mysql_use_result(sock)) {
while(row=mysql_fetch_row(result))
{
strcpy(&b[i][BUFLEN],row[0]);
DBUG_PRINT("info",("field %s at %x", &b[i*BUFLEN],&b[i*BUFLEN]));
// ptr = (*dynamic_element(&field_array,i,row[0]));
i++;
}
}
// fix_filenames((char *)b);
mysql_free_result(result);
*/
delete_dynamic(&field_array);
DBUG_RETURN(i);
}
int db_show_fields(char *b,const char *database,const char *table)
{
MYSQL_RES *result;
MYSQL_ROW row;
MYSQL_FIELD *field;
char buff[BUFLEN];
int i=0;
DBUG_ENTER("show_fields");
DBUG_PRINT("enter",("buffer: '%s', database: '%s', table: '%s'", b, database, table));
if (mysql_select_db(sock,database))
{
printf("error when changing database to'%s'\n",database);
DBUG_RETURN(-1);
}
if(result=mysql_list_fields(sock,buff,NULL)) {
while(row=mysql_fetch_row(result))
{
strcpy(&b[i*BUFLEN],row[0]);
DBUG_PRINT("info",("field %s at %x", &b[i*BUFLEN],&b[i*BUFLEN]));
i++;
}
}
mysql_free_result(result);
DBUG_RETURN(i);
}
int db_show_primary_keys(char *b,const char *database, const char *table)
{
MYSQL_RES *result;
MYSQL_ROW row;
char buff[BUFLEN];
char buff2[BUFLEN];
unsigned int i;
DBUG_ENTER("db_show_primary_keys");
DBUG_PRINT("enter",("buffer: '%s', database: '%s', table: '%s'", b, database, table));
if (mysql_select_db(sock,database))
{
printf("error when changing database to '%s'\n",database);
DBUG_RETURN(-1);
}
sprintf(buff,"show keys from %s",table);
if (mysql_query(sock, buff))
{
printf("error when executing '%s'\n",buff);
DBUG_RETURN(0);
}
buff2[0]='\0';
if(result=mysql_use_result(sock)) {
while(row=mysql_fetch_row(result)) {
if(!strcasecmp(row[2],"PRIMARY")) {
strcat(buff2,row[4]);
strcat(buff2,",\"_\",");
}
}
buff2[strlen(buff2)-5]='\0';
if(!buff2[0])
DBUG_RETURN(-1); // No PRIMARY keys in table
DBUG_PRINT("info",("Keys: %s<- \n", buff2));
} else
DBUG_RETURN(-1); // No keys in table
sprintf(buff,"SELECT CONCAT(%s) AS X FROM %s LIMIT 256",buff2,table);
if (mysql_query(sock, buff))
{
printf("error when executing '%s'\n",buff);
DBUG_RETURN(0);
}
i=0;
if(result=mysql_use_result(sock)) {
while(row=mysql_fetch_row(result))
{
strcpy(&b[i*BUFLEN],row[0]);
fix_filenames(&b[i*BUFLEN]);
DBUG_PRINT("info",("primarykey %s at %x, %i", &b[i*BUFLEN],&b[i*BUFLEN],i));
if(i++ >= MAXDIRS)
break;
}
}
mysql_free_result(result);
DBUG_RETURN(i);
}
int db_show_keys(char *b,const char *database, const char *table)
{
MYSQL_RES *result;
MYSQL_ROW row;
char buff[BUFLEN];
int i=0;
DBUG_ENTER("show_keys");
DBUG_PRINT("enter",("buffer: '%s', database: '%s', table: '%s'", b, database, table));
if (mysql_select_db(sock,database))
{
printf("error when changing database to'%s'\n",database);
DBUG_RETURN(-1);
}
sprintf(buff,"show keys from %s",table);
if (mysql_query(sock, buff))
{
printf("error when executing '%s'\n",buff);
DBUG_RETURN(0);
}
if(result=mysql_use_result(sock)) {
while(row=mysql_fetch_row(result))
{
strcpy(&b[i*BUFLEN],row[0]);
DBUG_PRINT("info",("Key %s at %x", &b[i*BUFLEN],&b[i*BUFLEN]));
i++;
}
}
mysql_free_result(result);
DBUG_RETURN(i);
}
int db_show_tables(char *b,const char *database)
{
MYSQL_RES *result;
MYSQL_ROW row;
char buff[BUFLEN];
int i=0;
DBUG_ENTER("db_show_tables");
DBUG_PRINT("enter",("buffer: '%s', database: '%s'", b, database));
if (mysql_select_db(sock,database))
{
printf("error when changing database to '%s'\n",database);
DBUG_RETURN(-1);
}
if(result=mysql_list_tables(sock,NULL)) {
while(row=mysql_fetch_row(result))
{
strcpy(&b[i*BUFLEN],row[0]);
DBUG_PRINT("info",("table %s at %x", &b[i*BUFLEN],&b[i*BUFLEN]));
i++;
}
}
mysql_free_result(result);
DBUG_RETURN(i);
}
/*
* Finds all servers we are connected to
* and stores them in array supplied.
* returns count of servers
*/
int
db_show_servers(char *b,int size)
{
char* bufptr;
char* buff[BUFLEN*2];
DBUG_ENTER("db_show_servers");
DBUG_PRINT("enter",("buffer: '%s', size: '%d'", b, size));
bufptr=mysql_get_host_info(sock);
// FIXME: Actually we need to escape prohibited symbols in filenames
fix_filenames(bufptr);
strcpy(b,bufptr);
DBUG_RETURN(1);
}
/*
* Finds all databases in server
* and stores them in array supplied.
* returns count of databases
*/
int
db_show_databases(char *b,int size)
{
MYSQL_RES *result;
MYSQL_ROW row;
char buff[BUFLEN];
int i=0;
DBUG_ENTER("db_show_databases");
DBUG_PRINT("enter",("buffer: '%s', size: '%d'", b, size));
result=mysql_list_dbs(sock,NULL);
while(row=mysql_fetch_row(result))
{
strcpy(&b[i*BUFLEN],row[0]);
DBUG_PRINT("info",("database %s at %x", &b[i*BUFLEN],&b[i*BUFLEN]));
i++;
}
mysql_free_result(result);
DBUG_RETURN(i);
}
void db_load_formats()
{
/* In future we should read these variables
* from configuration file/database here */
/* HTML output */
HTML.tablestart="<table>\n";
HTML.headerrowstart="<tr>";
HTML.headercellstart="<th>";
HTML.headercellseparator="</th><th>";
HTML.headercellend="</th>";
HTML.headerrowend="</tr>\n";
HTML.headerformat=0;
HTML.leftuppercorner="";
HTML.rightuppercorner="";
HTML.leftdowncorner="";
HTML.rightdowncorner="";
HTML.topcross="";
HTML.middlecross="";
HTML.bottomcross="";
HTML.leftcross="";
HTML.rightcross="";
HTML.bottomcross="";
HTML.contentrowstart="<tr>";
HTML.contentcellstart="<td>";
HTML.contentcellseparator="</td><td>";
HTML.contentcellend="</td>";
HTML.contentrowend="</tr>\n";
HTML.headerformat=0;
HTML.footerrowstart="";
HTML.footercellstart="";
HTML.footercellseparator="";
HTML.footercellend="";
HTML.footerrowend="\n";
HTML.footerformat=0;
HTML.tableend="</table>\n";
/* Nice to look mysql client like output */
Human.tablestart="\n";
Human.headerrowstart="| ";
Human.headercellstart="";
Human.headercellseparator=" | ";
Human.headercellend=" |";
Human.headerrowend="\n";
Human.headerformat=1;
Human.leftuppercorner="/=";
Human.rightuppercorner="=\\\n";
Human.leftdowncorner="\\=";
Human.rightdowncorner="=/\n";
Human.leftcross="+-";
Human.rightcross="-+\n";
Human.topcross="=T=";
Human.middlecross="-+-";
Human.bottomcross="=`=";
Human.contentrowstart="| ";
Human.contentcellstart="";
Human.contentcellseparator=" | ";
Human.contentcellend=" |";
Human.contentrowend="\n";
Human.contentformat=1;
Human.footerrowstart="";
Human.footercellstart="";
Human.footercellseparator="";
Human.footercellend="";
Human.footerrowend="\n";
Human.footerformat=1;
Human.tableend="\n";
/* Comma-separated format. For machine reading */
/* XML */
/*
tee_fprintf(PAGER,"<?xml version=\"1.0\"?>\n\n<resultset statement=\"%s\">", statement);
(void) tee_fputs("\n <row>\n", PAGER);
data=(char*) my_malloc(lengths[i]*5+1, MYF(MY_WME));
tee_fprintf(PAGER, "\t<%s>", (fields[i].name ?
(fields[i].name[0] ? fields[i].name :
" &nbsp; ") : "NULL"));
xmlencode(data, cur[i]);
tee_fprintf(PAGER, "</%s>\n", (fields[i].name ?
(fields[i].name[0] ? fields[i].name :
" &nbsp; ") : "NULL"));
</row>\n" </resultset>\n*/
}
gptr db_load_functions()
{
char *functions[]={
"database",".tables","SHOW TABLES","0",
"table",".status","SHOW TABLE STATUS FROM $table","0",
"table",".count","SELECT COUNT(*) FROM $table","0",
"table",".table","SELECT * FROM $table","0",
"table",".check","CHECK TABLE $table","0",
"table",".repair","REPAIR TABLE $table","0",
"key",".min","SELECT MIN($key) FROM $table","0",
"key",".max","SELECT MAX($key) FROM $table","0",
"key",".avg","SELECT AVG($key) FROM $table","0",
"server",".uptime","SHOW STATUS like 'Uptime'","0",
"server",".version","SELECT VERSION()","0",
"server",".execute","$*","1",
"root",".connect","CONNECT $*","0",
NULL,NULL,NULL,NULL
};
char buff[BUFLEN];
int i=0;
struct func_st func;
DBUG_ENTER("db_load_functions");
my_init_dynamic_array(&functions_array, sizeof(struct func_st), 4096, 1024);
while(functions[i]) {
strcpy(func.type_s, functions[i]); /* Type in string: "table"` */
strcpy(func.filename, functions[i+1]); /* Name like it appears on FS: "count" */
strcpy(func.function, functions[i+2]); /* Query: "SELECT COUNT(*) FROM `%table`" */
func.continuous= atoi(functions[i+3]); /* Query: "If command can be continued" */
if(!strcasecmp(func.type_s,"server"))
func.type=SERVER_FUNCTION;
else if(!strcasecmp(func.type_s,"table"))
func.type=TABLE_FUNCTION;
else if(!strcasecmp(func.type_s,"key"))
func.type=KEY_FUNCTION;
else if(!strcasecmp(func.type_s,"database"))
func.type=DATABASE_FUNCTION;
else if(!strcasecmp(func.type_s,"field"))
func.type=FIELD_FUNCTION;
else if(!strcasecmp(func.type_s,"root"))
func.type=ROOT_FUNCTION;
else func.type=NONE_FUNCTION;
func.length=strlen(func.filename); /* Filename length */
DBUG_PRINT("info",("func.type_s: %s",func.type_s));
DBUG_PRINT("info",("func.filename: %s",func.filename));
DBUG_PRINT("info",("func.function: %s",func.function));
DBUG_PRINT("info",("func.type: %d",func.type));
DBUG_PRINT("info",("func.continuous: %d",func.continuous));
DBUG_PRINT("info",("i: %d",i));
insert_dynamic(&functions_array,(gptr)&func);
i+=4;
}
DBUG_RETURN((gptr)&functions_array);
}
# MySQL dump 8.12
#
# Host: localhost Database: mysqlfs
#--------------------------------------------------------
# Server version 3.23.33
#
# Table structure for table 'functions'
#
CREATE TABLE functions (
type enum('server','database','table','field','key') NOT NULL default 'server',
name char(20) NOT NULL default '',
sql char(128) NOT NULL default '',
PRIMARY KEY (type,name)
) TYPE=MyISAM;
#
# Dumping data for table 'functions'
#
INSERT INTO functions VALUES ('server','uptime','SHOW STATUS like \'Uptime\'');
INSERT INTO functions VALUES ('server','version','SELECT VERSION()');
INSERT INTO functions VALUES ('table','count','SELECT COUNT(*) FROM `%table`');
INSERT INTO functions VALUES ('key','min','SELECT MIN(%key) FROM `%table`');
INSERT INTO functions VALUES ('key','max','SELECT MAX(%key) FROM `%table`');
INSERT INTO functions VALUES ('key','avg','SELECT AVG(%key) FROM `%table`');
This source diff could not be displayed because it is too large. You can view the blob instead.
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "libmysqlfs.h"
int search_and_replace(char *search, char* replace, char* string)
{
char buff[1024];
int found=0;
char *ptr1;
const char *ptr2=buff;
char *strptr=string;
DBUG_ENTER("search_and_replace");
DBUG_PRINT("enter",("search: '%s' replace:'%s' string:'%s'",search,replace,string));
strcpy(buff,string);
while(ptr1=strstr(ptr2,search))
{
strncpy(strptr,ptr2,ptr1-buff);
strptr+=ptr1-buff;
ptr2+=ptr1-buff+strlen(search);
strcpy(strptr,replace);
strptr+=strlen(replace);
found++;
}
DBUG_RETURN(found);
}
int show_functions(char *b, function_type type)
{
int i=0,j=0;
struct func_st func;
DBUG_ENTER("show_functions");
get_dynamic(&functions_array,(gptr)&func,i);
while(func.length) {
if (func.type == type)
strcpy(&b[j++*BUFLEN],func.filename);
get_dynamic(&functions_array,(gptr)&func,++i);
}
DBUG_RETURN(j);
}
struct func_st * check_if_function(char *name, function_type type)
{
int pathlen;
int j,i=0, len;
static struct func_st function;
char buffer[BUFLEN];
DBUG_ENTER("check_if_function");
DBUG_PRINT("enter",("name: '%s' type: '%d'", name, type));
pathlen=strlen(name);
/* We try to compare last element in path to function names */
get_dynamic(&functions_array,(gptr)&function,i);
while(function.length) {
function.continuous ?
(j=!strncasecmp(function.filename, name, function.length))
: (j=!strcasecmp(function.filename,name));
if(j) { /* This happens when function was matched */
DBUG_PRINT("info",("Function %s detected!",function.filename));
break;
}
get_dynamic(&functions_array,(gptr)&function,++i);
}
/* Copy path to buffer and trip function name (if found) from it */
if(function.length != 0)
{
DBUG_RETURN(&function);
} else {
DBUG_RETURN(0);
}
}
/*
* parse - splits "path" into different variables
* in way "/server/database/table/(field|key)/(value|function)". If path is shorter,
* then other fields will be NULL. If path is longer than four levels or
* shorter than one level, FS_NOTEXIST is returned.
*/
int parse(const char * path, char *server, char * database, char *table,
char* field, char* value, struct func_st **funce)
{
char buffer[BUFLEN];
char *p=buffer;
char *x;
int len;
DBUG_ENTER("parse");
DBUG_PRINT("enter",("path: '%s'", path));
*server=*database=*table=*field=*value='\0';
/* Search for first slash and drop it */
strcpy(buffer,path);
x=strtok_r(p,"/",&p);
if(x)
{
strcpy(server,x); /* First argument is server name */
if(*p)
strcpy(database,strtok_r(p,"/",&p)); /* Second is database */
if(p && *p)
strcpy(table ,strtok_r(p,"/",&p)); /* Third is table name */
if(p && *p)
strcpy(field ,strtok_r(p,"/",&p)); /* Fourth is field or key name */
if(p && *p)
strcpy(value ,strtok_r(p,"/",&p)); /* Fifth is field/key value or function */
}
/* We have to find if last argument is function,
* In which case we clear it
*/
if(*value) {
*funce=check_if_function(value,VALUE_FUNCTION);
if(*funce) *value='\0';
} else if (*field) {
*funce=check_if_function(field,FIELD_FUNCTION);
if(*funce) *field='\0';
} else if (*table) {
*funce=check_if_function(table,TABLE_FUNCTION);
if(*funce) *table='\0';
} else if (*database) {
*funce=check_if_function(database,DATABASE_FUNCTION);
if(*funce) *database='\0';
} else if (*server) {
*funce=check_if_function(server,SERVER_FUNCTION);
if(*funce) *server='\0';
} else
*funce=NULL;
DBUG_PRINT("info",("path: '%s', server: '%s', db: '%s', table: '%s', field: '%s', value: '%s', function: '%x'",
buffer, server, database, table, field, value, funce ));
if(p && *p) /* Something is in buffer - too deep in levels */
DBUG_RETURN(-1)
else
DBUG_RETURN(0)
}
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "CorbaFS.h"
#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <m_ctype.h>
#include "mysql.h"
#define BUFLEN 1024
#define MAXDIRS 1024
typedef enum {
FUNC_NONE,
FUNC_SERVER_UPTIME,
FUNC_SERVER_THREADS,
FUNC_SERVER_VERSION,
FUNC_DATABASE_CREATED,
FUNC_TABLE_COUNT,
FUNC_TABLE_CREATED,
FUNC_FIELD_LENGTH,
FUNC_KEY_AVG,
FUNC_KEY_SUM,
FUNC_KEY_MAX,
FUNC_KEY_MIN
} func_enum;
typedef enum {
NONE_FUNCTION,
ROOT_FUNCTION,
SERVER_FUNCTION,
DATABASE_FUNCTION,
TABLE_FUNCTION,
KEY_FUNCTION,
FIELD_FUNCTION,
VALUE_FUNCTION
} function_type;
struct func_st {
char type_s[20];
char filename[20];
char function[80];
function_type type;
int length;
my_bool continuous;
} ;
int parse(const char* path,
char* root,
char* database,
char* table,
char* key,
char* field,
struct func_st **func
);
gptr db_load_functions();
int db_function(char *b,const char *server, const char *database,const char *table,const char *field,
const char *value, const char *path, struct func_st *function);
int fix_filenames(char *buf);
DYNAMIC_ARRAY functions_array;
[mysqlcorbafs]
socket=/var/lib/mysql/mysql.sock
host=127.0.0.1
user=root
#password=xxxxxx
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
*
* fsck.mysql
*/
#include "libmysqlfs.h"
#include "mysqlcorbafs.h"
#include <my_getopt.h>
#define MAXPATHLEN 256
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <my_sys.h>
static long inodeNum;
extern DYNAMIC_ARRAY functions_array;
enum options {OPT_FTB=256, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_KEYWORDS,
OPT_LOCKS, OPT_DROP, OPT_OPTIMIZE, OPT_DELAYED, OPT_TABLES,
OPT_CHARSETS_DIR, OPT_DEFAULT_CHARSET};
CHANGEABLE_VAR changeable_vars[] = {
{ "max_allowed_packet", (long*) &max_allowed_packet,24*1024*1024,4096,
24*1024L*1024L,MALLOC_OVERHEAD,1024},
{ "net_buffer_length", (long*) &net_buffer_length,1024*1024L-1025,4096,
24*1024L*1024L,MALLOC_OVERHEAD,1024},
{ 0, 0, 0, 0, 0, 0, 0}
};
CORBA_ORB orb;
PortableServer_POA poa;
CORBA_Environment *ev;
PortableServer_ObjectId *objid;
static my_bool verbose=0,opt_compress=0,extended_insert=0, lock_tables=0,
opt_quoted=0, opt_lock=0, opt_delayed=0, ignore_errors=0;
gptr fptr;
static const char *load_default_groups[]= { "mysqlcorbafs","client",0 };
static char *default_charset, *current_host, *current_user, *opt_password,
*path,*fields_terminated=0, *lines_terminated=0, *enclosed=0,
*opt_enclosed=0, *escaped=0;
/* This should be fixed to use my_getopt when the program is ready
static struct option long_options[] =
{
{"add-locks", no_argument, 0,OPT_LOCKS},
{"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR},
{"compress", no_argument, 0, 'C'},
{"database",required_argument, 0, 'D'},
{"debug",optional_argument, 0, '#'},
{"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET},
{"delayed-insert",no_argument, 0, OPT_DELAYED},
{"fields-terminated-by", required_argument, 0, (int) OPT_FTB},
{"fields-enclosed-by", required_argument,0, (int) OPT_ENC},
{"fields-optionally-enclosed-by", required_argument, 0, (int) OPT_O_ENC},
{"fields-escaped-by", required_argument,0, (int) OPT_ESC},
{"functions",required_argument, 0, 'f'},
{"help", no_argument, 0,'?'},
{"host", required_argument,0, 'h'},
{"lines-terminated-by", required_argument, 0, (int) OPT_LTB},
{"lock-tables", no_argument, 0, 'l'},
{"no-data", no_argument, 0, 'd'},
{"password", optional_argument, 0, 'p'},
#ifdef __WIN__
{"pipe",no_argument,0, 'W'},
#endif
{"port", required_argument,0, 'P'},
// {"quick", no_argument,0, 'q'},
{"quote-names",no_argument,0, 'Q'},
{"set-variable",required_argument,0, 'O'},
{"socket", required_argument,0, 'S'},
#include "sslopt-longopts.h"
#ifndef DONT_ALLOW_USER_CHANGE
{"user", required_argument,0, 'u'},
#endif
{"verbose", no_argument,0, 'v'},
{"version", no_argument,0, 'V'},
{0, 0, 0, 0}
};
*/
/*
void
print_table_data(MYSQL_RES *result)
{
String separator(256);
MYSQL_ROW cur;
MYSQL_FIELD *field;
bool *num_flag;
num_flag=(bool*) my_alloca(sizeof(bool)*mysql_num_fields(result));
if (info_flag)
{
print_field_types(result);
mysql_field_seek(result,0);
}
separator.copy("+",1);
while ((field = mysql_fetch_field(result)))
{
uint length=skip_column_names ? 0 : (uint) strlen(field->name);
if (quick)
length=max(length,field->length);
else
length=max(length,field->max_length);
if (length < 4 && !IS_NOT_NULL(field->flags))
length=4; // Room for "NULL"
field->max_length=length+1;
separator.fill(separator.length()+length+2,'-');
separator.append('+');
}
tee_puts(separator.c_ptr(), PAGER);
if (!skip_column_names)
{
mysql_field_seek(result,0);
(void) tee_fputs("|", PAGER);
for (uint off=0; (field = mysql_fetch_field(result)) ; off++)
{
tee_fprintf(PAGER, " %-*s|",min(field->max_length,MAX_COLUMN_LENGTH),
field->name);
num_flag[off]= IS_NUM(field->type);
}
(void) tee_fputs("\n", PAGER);
tee_puts(separator.c_ptr(), PAGER);
}
while ((cur = mysql_fetch_row(result)))
{
(void) tee_fputs("|", PAGER);
mysql_field_seek(result,0);
for (uint off=0 ; off < mysql_num_fields(result); off++)
{
const char *str=cur[off] ? cur[off] : "NULL";
field = mysql_fetch_field(result);
uint length=field->max_length;
if (length > MAX_COLUMN_LENGTH)
{
tee_fputs(str,PAGER); tee_fputs(" |",PAGER);
}
else
tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|",
length, str);
}
(void) tee_fputs("\n", PAGER);
}
tee_puts(separator.c_ptr(), PAGER);
my_afree((gptr) num_flag);
}
void
print_table_data_html(MYSQL_RES *result)
{
MYSQL_ROW cur;
MYSQL_FIELD *field;
mysql_field_seek(result,0);
(void) tee_fputs("<TABLE BORDER=1><TR>", PAGER);
if (!skip_column_names)
{
while((field = mysql_fetch_field(result)))
{
tee_fprintf(PAGER, "<TH>%s</TH>", (field->name ?
(field->name[0] ? field->name :
" &nbsp; ") : "NULL"));
}
(void) tee_fputs("</TR>", PAGER);
}
while ((cur = mysql_fetch_row(result)))
{
(void) tee_fputs("<TR>", PAGER);
for (uint i=0; i < mysql_num_fields(result); i++)
{
ulong *lengths=mysql_fetch_lengths(result);
(void) tee_fputs("<TD>", PAGER);
safe_put_field(cur[i],lengths[i]);
(void) tee_fputs("</TD>", PAGER);
}
(void) tee_fputs("</TR>", PAGER);
}
(void) tee_fputs("</TABLE>", PAGER);
}
void
print_table_data_xml(MYSQL_RES *result)
{
MYSQL_ROW cur;
MYSQL_FIELD *fields;
mysql_field_seek(result,0);
char *statement;
statement=(char*) my_malloc(strlen(glob_buffer.ptr())*5+1, MYF(MY_WME));
xmlencode(statement, (char*) glob_buffer.ptr());
(void) my_chomp(strend(statement));
tee_fprintf(PAGER,"<?xml version=\"1.0\"?>\n\n<resultset statement=\"%s\">", statement);
my_free(statement,MYF(MY_ALLOW_ZERO_PTR));
fields = mysql_fetch_fields(result);
while ((cur = mysql_fetch_row(result)))
{
(void) tee_fputs("\n <row>\n", PAGER);
for (uint i=0; i < mysql_num_fields(result); i++)
{
char *data;
ulong *lengths=mysql_fetch_lengths(result);
data=(char*) my_malloc(lengths[i]*5+1, MYF(MY_WME));
tee_fprintf(PAGER, "\t<%s>", (fields[i].name ?
(fields[i].name[0] ? fields[i].name :
" &nbsp; ") : "NULL"));
xmlencode(data, cur[i]);
safe_put_field(data, strlen(data));
tee_fprintf(PAGER, "</%s>\n", (fields[i].name ?
(fields[i].name[0] ? fields[i].name :
" &nbsp; ") : "NULL"));
my_free(data,MYF(MY_ALLOW_ZERO_PTR));
}
(void) tee_fputs(" </row>\n", PAGER);
}
(void) tee_fputs("</resultset>\n", PAGER);
}
void
print_table_data_vertically(MYSQL_RES *result)
{
MYSQL_ROW cur;
uint max_length=0;
MYSQL_FIELD *field;
while ((field = mysql_fetch_field(result)))
{
uint length=(uint) strlen(field->name);
if (length > max_length)
max_length= length;
field->max_length=length;
}
mysql_field_seek(result,0);
for (uint row_count=1; (cur= mysql_fetch_row(result)); row_count++)
{
mysql_field_seek(result,0);
tee_fprintf(PAGER,
"*************************** %d. row ***************************\n", row_count);
for (uint off=0; off < mysql_num_fields(result); off++)
{
field= mysql_fetch_field(result);
tee_fprintf(PAGER, "%*s: ",(int) max_length,field->name);
tee_fprintf(PAGER, "%s\n",cur[off] ? (char*) cur[off] : "NULL");
}
}
}
*/
static my_bool test_if_special_chars(const char *str)
{
for ( ; *str ; str++)
if (!isvar(*str) && *str != '$')
return 1;
return 0;
} /* test_if_special_chars */
char *quote_name(char *name, char *buff)
{
char *end;
DBUG_ENTER("quote_name");
if (!opt_quoted && !test_if_special_chars(name))
return name;
buff[0]=QUOTE_CHAR;
*end=strmov(buff+1,name);
end[0]=QUOTE_CHAR;
end[1]=0;
DBUG_RETURN(buff);
} /* quote_name */
/*
* Allow the user to specify field terminator strings like:
* "'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
* This is done by doubleing ' and add a end -\ if needed to avoid
* syntax errors from the SQL parser.
*/
char *field_escape(char *to,const char *from,uint length)
{
const char *end;
uint end_backslashes=0;
DBUG_ENTER("field_escape");
{
*to++= *from;
if (*from == '\\')
end_backslashes^=1; /* find odd number of backslashes */
else {
if (*from == '\'' && !end_backslashes)
*to++= *from; /* We want a duplicate of "'" for MySQL */
end_backslashes=0;
}
}
/* Add missing backslashes if user has specified odd number of backs.*/
if (end_backslashes)
*to++= '\\';
DBUG_RETURN(to);
} /* field_escape */
void safe_exit(int error)
{
if (!first_error)
first_error= error;
if (ignore_errors)
return;
if (sock)
mysql_close(sock);
exit(error);
}
/* safe_exit */
/*
* ** DBerror -- prints mysql error message and exits the program.
*/
void DBerror(MYSQL *mysql, const char *when)
{
DBUG_ENTER("DBerror");
my_printf_error(0,"Got error: %d: %s %s", MYF(0),
mysql_errno(mysql), mysql_error(mysql), when);
safe_exit(EX_MYSQLERR);
DBUG_VOID_RETURN;
} /* DBerror */
void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,CORBAFS_VERSION,
MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
} /* print_version */
void usage(void)
{
uint i;
print_version();
puts("By Tnu Samuel. Some code is partially from other geeks around the world");
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
puts("Dumping definition and data mysql database or table");
printf("Usage: %s [OPTIONS]\n", my_progname);
printf("\n\
-#, --debug=... Output debug log. Often this is 'd:t:o,filename`.\n\
--character-sets-dir=...\n\
Directory where character sets are\n\
-?, --help Display this help message and exit.\n\
-c, --complete-insert Use complete insert statements.\n\
-C, --compress Use compression in server/client protocol.\n\
--default-character-set=...\n\
Set the default character set\n\
-e, --extended-insert Allows utilization of the new, much faster\n\
INSERT syntax.\n\
--add-locks Add locks around insert statements.\n\
--allow-keywords Allow creation of column names that are keywords.\n\
--delayed-insert Insert rows with INSERT DELAYED.\n\
-f, --force Continue even if we get an sql-error.\n\
-h, --host=... Connect to host.\n");
puts("\
-l, --lock-tables Lock all tables for read.\n\
-t, --no-create-info Don't write table creation info.\n\
-d, --no-data No row information.\n\
-O, --set-variable var=option\n\
give a variable a value. --help lists variables\n\
-p, --password[=...] Password to use when connecting to server.\n\
If password is not given it's solicited on the tty.\n");
#ifdef __WIN__
puts("-W, --pipe Use named pipes to connect to server");
#endif
printf("\
-P, --port=... Port number to use for connection.\n\
-q, --quick Don't buffer query, dump directly to stdout.\n\
-S, --socket=... Socket file to use for connection.\n\
--tables Overrides option --databases (-B).\n");
#include "sslopt-usage.h"
#ifndef DONT_ALLOW_USER_CHANGE
printf("\
-u, --user=# User for login if not current user.\n");
#endif
printf("\
-v, --verbose Print info about the various stages.\n\
-V, --version Output version information and exit.\n\
");
print_defaults("my",load_default_groups);
printf("\nPossible variables for option --set-variable (-O) are:\n");
for (i=0 ; changeable_vars[i].name ; i++)
printf("%-20s current value: %lu\n",
changeable_vars[i].name,
(ulong) *changeable_vars[i].varptr);
} /* usage */
static int get_options(int *argc,char ***argv)
{
int c,option_index;
my_bool tty_password=0;
DBUG_ENTER("get_options");
load_defaults("my",load_default_groups,argc,argv);
/* change this to use my_getopt when program is ready */
set_all_changeable_vars(changeable_vars);
while ((c=getopt_long(*argc,*argv,"#::p::h:u:O:P:S:T:EBaAcCdefFlnqtvVw:?Ix",
long_options, &option_index)) != EOF)
{
switch(c) {
case 'e':
extended_insert=1;
break;
case OPT_DEFAULT_CHARSET:
default_charset= optarg;
break;
case OPT_CHARSETS_DIR:
charsets_dir= optarg;
break;
ignore_errors=1;
break;
case 'h':
my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
current_host=my_strdup(optarg,MYF(MY_WME));
break;
#ifndef DONT_ALLOW_USER_CHANGE
case 'u':
current_user=optarg;
break;
#endif
case 'O':
if (set_changeable_var(optarg, changeable_vars))
{
usage();
return(1);
}
break;
case 'p':
if (optarg)
{
char *start=optarg;
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
opt_password=my_strdup(optarg,MYF(MY_FAE));
while (*optarg) *optarg++= 'x'; /* Destroy argument */
if (*start)
start[1]=0; /* Cut length of argument */
} else
tty_password=1;
break;
case 'P':
opt_mysql_port= (unsigned int) atoi(optarg);
break;
case 'S':
opt_mysql_unix_port= optarg;
break;
case 'W':
#ifdef __WIN__
opt_mysql_unix_port=MYSQL_NAMEDPIPE;
#endif
break;
case 'T':
path= optarg;
break;
case '#':
DBUG_PUSH(optarg ? optarg : "d:t:o");
break;
case 'C':
opt_compress=1;
break;
case 'l': lock_tables=1; break;
case 'Q': opt_quoted=1; break;
case 'v': verbose=1; break;
case 'V': print_version(); exit(0);
default:
fprintf(stderr,"%s: Illegal option character '%c'\n",my_progname,opterr);
/* Fall throught */
case 'I':
case '?':
usage();
exit(0);
case (int) OPT_FTB:
fields_terminated= optarg;
break;
case (int) OPT_LTB:
lines_terminated= optarg;
break;
case (int) OPT_ENC:
enclosed= optarg;
break;
case (int) OPT_O_ENC:
opt_enclosed= optarg;
break;
case (int) OPT_ESC:
escaped= optarg;
break;
case (int) OPT_LOCKS:
opt_lock=1;
break;
case (int) OPT_OPTIMIZE:
extended_insert=opt_lock=lock_tables=1;
break;
case (int) OPT_DELAYED:
opt_delayed=1;
break;
#include "sslopt-case.h"
}
}
if (opt_delayed)
opt_lock=0; /* Can't have lock with delayed */
if (!path && (enclosed || opt_enclosed || escaped || lines_terminated ||
fields_terminated))
{
fprintf(stderr, "%s: You must use option --tab with --fields-...\n", my_progname);
return(1);
}
if (enclosed && opt_enclosed)
{
fprintf(stderr, "%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n", my_progname);
return(1);
}
if (default_charset)
{
if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
exit(1);
}
(*argc)-=optind;
(*argv)+=optind;
if (tty_password)
opt_password=get_tty_password(NullS);
DBUG_RETURN(0);
} /* get_options */
/*** epv structures ***/
static PortableServer_ServantBase__epv impl_Inode_base_epv = {
NULL, /* _private data */
NULL, /* finalize routine */
NULL, /* default_POA routine */
};
static POA_CorbaFS_Inode__epv impl_Inode_epv = {
NULL, /* _private */
(gpointer) & impl_Inode_getStatus,
(gpointer) & impl_Inode_readpage,
(gpointer) & impl_Inode_release,
};
static PortableServer_ServantBase__epv impl_FileSystem_base_epv = {
NULL, /* _private data */
NULL, /* finalize routine */
NULL, /* default_POA routine */
};
static POA_CorbaFS_FileSystem__epv impl_FileSystem_epv = {
NULL, /* _private */
(gpointer) & impl_FileSystem_getInode,
(gpointer) & impl_FileSystem_readdir,
(gpointer) & impl_FileSystem_readlink,
};
/*** vepv structures ***/
static POA_CorbaFS_Inode__vepv impl_Inode_vepv = {
&impl_Inode_base_epv,
&impl_Inode_epv,
};
static POA_CorbaFS_FileSystem__vepv impl_FileSystem_vepv = {
&impl_FileSystem_base_epv,
&impl_FileSystem_epv,
};
/*** Stub implementations ***/
static CorbaFS_Inode
impl_Inode__create(PortableServer_POA poa, CORBA_Environment * ev)
{
CorbaFS_Inode retval;
impl_POA_CorbaFS_Inode *newservant;
PortableServer_ObjectId *objid;
DBUG_ENTER("impl_Inode__create");
newservant = g_new0(impl_POA_CorbaFS_Inode, 1);
newservant->servant.vepv = &impl_Inode_vepv;
newservant->poa = poa;
POA_CorbaFS_Inode__init((PortableServer_Servant) newservant, ev);
objid = PortableServer_POA_activate_object(poa, newservant, ev);
CORBA_free(objid);
retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
DBUG_RETURN(retval);
}
static void
impl_Inode__destroy(impl_POA_CorbaFS_Inode * servant,
CORBA_Environment * ev)
{
PortableServer_ObjectId *objid;
DBUG_ENTER("impl_Inode__destroy");
objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
PortableServer_POA_deactivate_object(servant->poa, objid, ev);
CORBA_free(objid);
POA_CorbaFS_Inode__fini((PortableServer_Servant) servant, ev);
g_free(servant);
DBUG_VOID_RETURN;
}
static void
impl_Inode_getStatus(impl_POA_CorbaFS_Inode * servant,
CORBA_unsigned_short * mode,
CORBA_unsigned_long * uid,
CORBA_unsigned_long * gid,
CORBA_unsigned_long * size,
CORBA_unsigned_long * inodeNum,
CORBA_unsigned_short * numLinks,
CORBA_long * atime,
CORBA_long * mtime,
CORBA_long * ctime, CORBA_Environment * ev)
{
struct stat buf;
char
server[BUFLEN],
database[BUFLEN],
table[BUFLEN],
key[BUFLEN],
field[BUFLEN],
value[BUFLEN];
struct func_st *func;
DBUG_ENTER("impl_Inode_getStatus");
DBUG_PRINT("enter",("path: '%s', mode: '%o', uid: '%d', gid: '%d', size: '%d',
inodeNum: '%d', numLinks: '%d', atime: '%d',mtime: '%d', ctime: '%d'",
servant->path, mode, uid, gid, size, inodeNum, numLinks, atime, mtime, ctime));
DBUG_PRINT("info",("func: %x",&func));
if(parse(servant->path, server, database, table, field, value, &func)>0)
{
DBUG_PRINT("info",("ENOENT"));
*mode=0;
} else if (func != NULL){
DBUG_PRINT("info",("func: %x",&func));
DBUG_PRINT("info",("Argument is function at %x, returning S_IFREG",func));
*mode = S_IFREG; // File
} else if (*field){
DBUG_PRINT("info",("Argument is file, returning S_IFREG"));
*mode = S_IFREG; // File
} else {
DBUG_PRINT("info",("Argument is directory, returning S_IFDIR"));
*mode = S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH ; // Dir
}
*mode |= S_IRUSR | S_IRGRP | S_IROTH;
*uid = 0;
*gid = 0;
*size = 4096;
*inodeNum = servant->inodeNum;
*numLinks = 1;
*atime = 3;
*mtime = 2;
*ctime = 1;
// lstat(servant->path, &buf);
// *mode = buf.st_mode;
/* *uid = buf.st_uid;
*gid = buf.st_gid;
*size = buf.st_size;
*inodeNum = buf.st_ino;
*numLinks = buf.st_nlink;
*atime = buf.st_atime;
*mtime = buf.st_mtime;
*ctime = buf.st_ctime;*/
DBUG_VOID_RETURN;
}
static void
impl_Inode_readpage(impl_POA_CorbaFS_Inode * servant,
CorbaFS_Buffer ** buffer,
CORBA_long size,
CORBA_long offset, CORBA_Environment * ev)
{
int type;
int fd = -1, c = 0;
int res;
char
server[BUFLEN],
database[BUFLEN],
table[BUFLEN],
key[BUFLEN],
field[BUFLEN],
value[BUFLEN];
struct func_st *func;
DBUG_ENTER("impl_Inode_readpage");
DBUG_PRINT("enter",("path: '%s'", servant->path));
*buffer = CorbaFS_Buffer__alloc();
(*buffer)->_maximum = size;
(*buffer)->_buffer = CORBA_octet_allocbuf(size);
printf("requested to read %d bytes\n",size);
memset((*buffer)->_buffer, size, 0);
type = parse(servant->path, server, database, table, field, value, &func);
if (func != NULL)
res=db_function((*buffer)->_buffer, server, database, table, field, value, servant->path, func);
else
res=db_show_field((*buffer)->_buffer, database, table, field, path, value);
if(res>0)
(*buffer)->_length = strlen((*buffer)->_buffer);
else
(*buffer)->_length = 0;
/*
fd = open(servant->path, O_RDONLY);
printf("Inode_readpage : fd = %d\n", fd);
lseek(fd, offset, SEEK_SET);
c = read(fd, (*buffer)->_buffer, size);
printf("Inode_readpage : read %d bytes\n", c);
(*buffer)->_length = c;
close(fd);
*/
DBUG_VOID_RETURN;
}
static void
impl_Inode_release(impl_POA_CorbaFS_Inode * servant,
CORBA_Environment * ev)
{
DBUG_ENTER("impl_Inode_readpage");
DBUG_PRINT("enter",("path: '%s'", servant->path));
DBUG_VOID_RETURN;
}
/*
* This function is called when we get mounted
*/
CorbaFS_FileSystem
impl_FileSystem__create(PortableServer_POA poa,
CORBA_Environment * ev)
{
CorbaFS_FileSystem retval;
impl_POA_CorbaFS_FileSystem *newservant;
PortableServer_ObjectId *objid;
DBUG_ENTER("impl_FileSystem__create");
newservant = g_new0(impl_POA_CorbaFS_FileSystem, 1);
newservant->servant.vepv = &impl_FileSystem_vepv;
newservant->poa = poa;
POA_CorbaFS_FileSystem__init((PortableServer_Servant) newservant, ev);
objid = PortableServer_POA_activate_object(poa, newservant, ev);
CORBA_free(objid);
retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
DBUG_RETURN(retval);
}
/*
* This function is called when we get unmounted
*/
static void
impl_FileSystem__destroy(impl_POA_CorbaFS_FileSystem * servant,
CORBA_Environment * ev)
{
PortableServer_ObjectId *objid;
DBUG_ENTER("impl_FileSystem__destroy");
objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
PortableServer_POA_deactivate_object(servant->poa, objid, ev);
CORBA_free(objid);
POA_CorbaFS_FileSystem__fini((PortableServer_Servant) servant, ev);
g_free(servant);
DBUG_VOID_RETURN;
}
static CorbaFS_Inode
impl_FileSystem_getInode(impl_POA_CorbaFS_FileSystem * servant,
CORBA_char * path, CORBA_Environment * ev)
{
CorbaFS_Inode retval;
impl_POA_CorbaFS_Inode *inode;
char
database[BUFLEN],
table[BUFLEN],
key[BUFLEN],
field[BUFLEN];
char buffer[MAXDIRS][BUFLEN];
int c;
DBUG_ENTER("impl_FileSystem_getInode");
DBUG_PRINT("enter",("path: '%s'", path));
//FIXME: We should verify the existense of file/dir here
//
retval = impl_Inode__create(servant->poa, ev);
inode = PortableServer_POA_reference_to_servant( servant->poa, retval, ev );
inode->path = CORBA_string_dup(path);
//FIXME: inodeNum Generation goes here
//
inode->inodeNum= inodeNum++;
#if 0
inode->mode = 0040777; /* world-readable directory */
inode->uid = 0;
inode->gid = 0;
inode->size = 4096;
inode->inodeNum = inodeNum++;
inode->numLinks = 1;
inode->atime = 0;
inode->mtime = 100;
inode->ctime = 10000;
#endif
DBUG_RETURN(retval);
}
static CorbaFS_DirEntSeq *
impl_FileSystem_readdir(impl_POA_CorbaFS_FileSystem * servant,
CORBA_char * path, CORBA_Environment * ev)
{
CorbaFS_DirEntSeq *retval;
CorbaFS_dirent *dirent;
struct func_st *func;
int c, c2,i;
char
server[BUFLEN],
table[BUFLEN],
field[BUFLEN],
value[BUFLEN],
buffer[MAXDIRS][BUFLEN],
buffer2[MAXDIRS][BUFLEN],
database[BUFLEN];
DBUG_ENTER("impl_FileSystem_readdir");
DBUG_PRINT("enter",("path: '%s'", path));
retval = CorbaFS_DirEntSeq__alloc();
retval->_maximum = 0;
retval->_length = 0;
parse(path, server, database, table, field, value, &func);
if (func != NULL) {
c2 = db_function((char *)buffer, server, database, table, field, value, path, func);
} else if(!*server) {
c2 = db_show_servers(buffer2,MAXDIRS);
c = show_functions((char *)buffer, ROOT_FUNCTION);
} else if(!*database) {
c2 = db_show_databases(buffer2,MAXDIRS);
c = show_functions((char *)buffer, SERVER_FUNCTION);
} else if(!*table){
c2 = db_show_tables(buffer2, database);
c = show_functions((char *)buffer, DATABASE_FUNCTION);
} else if(!*field){
c2 = db_show_primary_keys(buffer2, database,table);
if(c2>=0) {
c = show_functions((char *)buffer, TABLE_FUNCTION);
}
} else {
c2 = db_show_fields(buffer2, database, table, field);
c = show_functions((char *)buffer, FIELD_FUNCTION);
c = show_functions((char *)buffer, KEY_FUNCTION);
}
if(c2 < 0)
c=c2=0; // Error occured in database routines
/* Allocate space to hold all found entries plus "." and ".." */
retval->_maximum = c + c2 + 2;
retval->_buffer = CORBA_sequence_CorbaFS_dirent_allocbuf(retval->_maximum) ;
dirent = retval->_buffer;
i = 0;
while (i < c) {
long inode = 123L;
dirent[i].inode = inode;
dirent[i].name = CORBA_string_dup(buffer[i]);
i++;
}
i = 0;
while (i < c2) {
long inode = 123L;
dirent[c+i].inode = inode;
dirent[c+i].name = CORBA_string_dup(buffer2[i]);
i++;
}
dirent[c+i].inode = 123L;
dirent[c+i].name = CORBA_string_dup(".");
i++;
dirent[c+i].inode = 123L;
dirent[c+i].name = CORBA_string_dup("..");
retval->_length = retval->_maximum;
DBUG_RETURN(retval);
}
static CORBA_char *
impl_FileSystem_readlink(impl_POA_CorbaFS_FileSystem * servant,
CORBA_char * filename,
CORBA_Environment * ev)
{
CORBA_char *retval = CORBA_OBJECT_NIL;
char tmp[MAXPATHLEN + 1];
int len;
DBUG_ENTER("impl_FileSystem_readlink");
DBUG_PRINT("enter",("path: '%s'", filename));
/* len = readlink(filename, tmp, MAXPATHLEN);
if (len != -1)
{
tmp[len] = '\0';
retval = CORBA_string_dup(tmp);
}
printf("%s\n", retval);
*/
DBUG_RETURN(retval);
}
int fix_filenames(char *buf)
{
int i;
for(i=0; i<strlen(buf);i++)
if(buf[i]=='/')
buf[i]='_';
}
int main(int argc, char *argv[]) {
CorbaFS_FileSystem fs;
impl_POA_CorbaFS_FileSystem *fs_impl;
FILE *f;
PortableServer_POAManager pm;
DBUG_ENTER("main");
DBUG_PROCESS(argv[0]);
ev = g_new0(CORBA_Environment,1);
CORBA_exception_init(ev);
orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
MY_INIT(argv[0]);
/*
** Check out the args
*/
if (get_options(&argc, &argv))
{
my_end(0);
exit(EX_USAGE);
}
if (db_connect(current_host, current_user, opt_password))
exit(EX_MYSQLERR);
fptr = db_load_functions();
db_load_formats();
poa = (PortableServer_POA)
CORBA_ORB_resolve_initial_references(orb, "RootPOA", ev);
fs = impl_FileSystem__create(poa, ev);
pm = PortableServer_POA__get_the_POAManager(poa, ev);
PortableServer_POAManager_activate(pm, ev);
fs_impl = PortableServer_POA_reference_to_servant( poa, fs, ev );
objid = PortableServer_POA_servant_to_id( poa, fs_impl, ev );
printf("CorbaFS-server:\n%s\n", CORBA_ORB_object_to_string(orb, fs, ev));
f=fopen("/tmp/mysqlcorbafs.ior","w");
fputs(CORBA_ORB_object_to_string(orb, fs, ev),f);
fclose(f);
CORBA_ORB_run(orb, ev);
db_disconnect(current_host);
return 0;
}
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "CorbaFS.h"
#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <m_ctype.h>
#include "mysql.h"
#define QUOTE_CHAR '`'
/* Exit codes */
#define EX_USAGE 1
#define EX_MYSQLERR 2
#define EX_CONSCHECK 3
#define EX_EOM 4
#define CORBAFS_VERSION "0.01"
typedef struct
{
POA_CorbaFS_Inode servant;
PortableServer_POA poa;
CORBA_char *path;
CORBA_unsigned_long inodeNum;
#if 0
CORBA_unsigned_short mode;
CORBA_unsigned_long uid;
CORBA_unsigned_long gid;
CORBA_unsigned_long size;
CORBA_unsigned_short numLinks;
CORBA_long atime;
CORBA_long mtime;
CORBA_long ctime;
#endif
}
impl_POA_CorbaFS_Inode;
typedef struct
{
POA_CorbaFS_FileSystem servant;
PortableServer_POA poa;
}
impl_POA_CorbaFS_FileSystem;
/*** Implementation stub prototypes ***/
CorbaFS_FileSystem
impl_FileSystem__create(PortableServer_POA poa, CORBA_Environment * ev);
static void
impl_Inode__destroy(impl_POA_CorbaFS_Inode * servant,
CORBA_Environment * ev);
static void
impl_Inode_getStatus(impl_POA_CorbaFS_Inode * servant,
CORBA_unsigned_short * mode,
CORBA_unsigned_long * uid,
CORBA_unsigned_long * gid,
CORBA_unsigned_long * size,
CORBA_unsigned_long * inodeNum,
CORBA_unsigned_short * numLinks,
CORBA_long * atime,
CORBA_long * mtime,
CORBA_long * ctime, CORBA_Environment * ev);
static void
impl_Inode_readpage(impl_POA_CorbaFS_Inode * servant,
CorbaFS_Buffer ** buffer,
CORBA_long size,
CORBA_long offset, CORBA_Environment * ev);
static void
impl_Inode_release(impl_POA_CorbaFS_Inode * servant,
CORBA_Environment * ev);
static void impl_FileSystem__destroy(impl_POA_CorbaFS_FileSystem *
servant, CORBA_Environment * ev);
static CorbaFS_Inode
impl_FileSystem_getInode(impl_POA_CorbaFS_FileSystem * servant,
CORBA_char * path, CORBA_Environment * ev);
static CorbaFS_DirEntSeq *
impl_FileSystem_readdir(impl_POA_CorbaFS_FileSystem * servant,
CORBA_char * path,
CORBA_Environment * ev);
static CORBA_char *
impl_FileSystem_readlink(impl_POA_CorbaFS_FileSystem * servant,
CORBA_char * filename,
CORBA_Environment * ev);
static my_bool verbose,opt_compress;
static uint opt_mysql_port=0;
static my_string opt_mysql_unix_port=0;
static int first_error=0;
static MYSQL connection, *sock=0;
extern uint opt_mysql_port;
extern my_string opt_mysql_unix_port,host,user,password;
static struct format {
char *tablestart;
char *headerrowstart;
char *headercellstart;
char *headercellseparator;
char *headercellend;
char *headerrowend;
int headerformat; /* 0 - simple, 1 - left padded, 2 - right padded */
char *contentrowstart;
char *contentcellstart;
char *contentcellseparator;
char *contentcellend;
char *contentrowend;
int contentformat;
char *footerrowstart;
char *footercellstart;
char *footercellseparator;
char *footercellend;
char *footerrowend;
int footerformat;
char *tableend;
char *leftuppercorner;
char *rightuppercorner;
char *leftdowncorner;
char *rightdowncorner;
char *leftcross;
char *rightcross;
char *topcross;
char *middlecross;
char *bottomcross;
} Human, HTML, CSF, XML;
#include <stdio.h>
#include <stdlib.h>
#include <orb/orbit.h>
#include "CorbaFS.h"
CorbaFS_FileSystem fs;
int
main (int argc, char *argv[])
{
CORBA_Environment ev;
CORBA_ORB orb;
CorbaFS_Inode inode;
CorbaFS_Buffer *buffer;
CorbaFS_DirEntSeq *dirents;
CorbaFS_dirent *dirent;
CORBA_unsigned_short mode;
CORBA_unsigned_long uid;
CORBA_unsigned_long gid;
CORBA_unsigned_long size;
CORBA_unsigned_long inodeNum;
CORBA_unsigned_short numLinks;
CORBA_long atime;
CORBA_long mtime;
CORBA_long ctime;
int i;
int niters = 10;
CORBA_exception_init(&ev);
orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
if(argc < 2)
{
printf("Need a binding ID thing as argv[1]\n");
return 1;
}
fs = CORBA_ORB_string_to_object(orb, argv[1], &ev);
if (!fs) {
printf("Cannot bind to %s\n", argv[1]);
return 1;
}
if (argc >= 3)
inode = CorbaFS_FileSystem_getInode(fs, argv[2], &ev);
else
inode = CorbaFS_FileSystem_getInode(fs, "/proc/cpuinfo", &ev);
if (!inode)
{
printf("Cannot get inode\n");
}
CorbaFS_Inode_getStatus(inode,
&mode,
&uid,
&gid,
&size,
&inodeNum,
&numLinks,
&atime,
&mtime,
&ctime,
&ev);
printf("inode = %x\n", inode);
CorbaFS_Inode_readpage(inode, &buffer, 100000, 100, &ev);
printf("readpage got %d bytes\n", buffer->_length);
printf("readpage returned : %s\n", buffer->_buffer);
if (argc >= 3)
dirents = CorbaFS_FileSystem_readdir(fs, argv[2], &ev);
else
dirents = CorbaFS_FileSystem_readdir(fs, "/", &ev);
dirent = dirents->_buffer;
for (i = 0; i < dirents->_length; i++)
{
printf("%d = %s\n", dirent->inode, dirent->name);
dirent++;
}
CORBA_Object_release(fs, &ev);
CORBA_Object_release((CORBA_Object)orb, &ev);
return 0;
}
#!/bin/sh
mountpoint=$*
if [#($mountpoint) -eq "0"];
then
exit;
fi
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef __GNUC__
#pragma implementation /* gcc: Class implementation */
#endif
#include <my_global.h>
#include <my_sys.h>
#include "cache_manager.h"
/*
cache_manager.cc
-----------------------------------------------------------------------
The cache_manager class manages a number of blocks (which are allocatable
units of memory).
-----------------------------------------------------------------------
*/
#define HEADER_LENGTH ALIGN_SIZE(8)
#define SUFFIX_LENGTH 4
#define ALLOC_MASK 0x3FFFFFFFL
#define FREE_BIT (1L << 31)
#define LOCK_BIT (1L << 30)
#define SMALLEST_BLOCK 32
/*
** Internal Methods
** --------------------
*/
/* list manipulation methods */
void *cache_manager::init_list(void)
{
return;
}
void *cache_manager::link_into_abs(void *ptr)
{
for (int i(0); (*abs_list)[i] != NULL; i++);
(*abs_list)[i] = ptr;
return (abs_list)[i]; // ???
}
bool *cache_manager::unlink_from_abs(void *ptr)
{
(*ptr) = NULL;
return;
}
/* memory allocation methods */
void *cache_manager::find_in_llist(uint)
{
return;
}
void cache_manager::defrag(void)
{
printf("Defragging: ..........");
return;
}
/*
** Public Methods
** ------------------
*/
cache_manager::cache_manager(uint size)
{
base_ptr = my_malloc(size, MY_WME); /* MY_WME = write mesg on err */
return;
}
cache_manager::~cache_manager(void)
{
free(base_ptr);
delete base_ptr;
return;
}
void *cache_manager::alloc(uint size)
{
void *llist;
void *abs_ptr;
size=ALIGN_SIZE(size+HEADER_LENGTH+SUFFIX_LENGTH);
if (!(llist = find_in_llist(size)))
{
//defrag();
if (!(llist = find_in_llist(size)))
return 0; /* return null pointer, buffer exhausted! */
}
size_of_found_block=int4korr((char*) llist) & ALLOC_MASK;
// if (size_of_found_block < SMALLEST_BLOCK)
abs_ptr = link_into_abs(llist);
return abs_ptr;
}
void cache_manager::dealloc(void)
{
printf("Deallocating: ..........\n");
return;
}
void cache_manager::clear(void)
{
// reset the internal linked list, forgetting all pointers to mem blks
return;
}
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
#endif
#ifndef _CACHE_MANAGER_H_
#define _CACHE_MANAGER_H_
#endif
/*
cache_manager.h
-----------------------------------------------------------------------
The cache_manager class manages a number of blocks (which are allocatable
units of memory).
-----------------------------------------------------------------------
*/
class cache_manager {
void **abs_list; /* List holding block abstraction ptrs */
typedef struct free_blks {
struct free_blks *next, **prev;
uint Size;
} FREE_BLKS;
FREE_BLKS *base_ptr; /* Pointer to newly allocated sys mem */
/* list manipulation methods */
void *link_into_abs(void *); /* Return an abstract pointer to blk */
bool *unlink_from_abs(void *); /* Used to dealloc a blk */
void *find_in_fblist(uint); /* */
/* memory allocation methods */
void defrag(void); /* Defragment the cache */
bool *init_blk(void *); /* Return a pointer to new list */
public:
cache_manager(uint); /* Get allocation of size from system */
~cache_manager(void); /* Destructor; return the cache */
void *alloc(uint); /* Alloc size bytes from the cache */
bool *dealloc(void *); /* Deallocate blocks (with *ptr_arg) */
void clear(void); /* Clear the cache */
};
...@@ -1457,12 +1457,13 @@ String *Item_func_user::val_str(String *str) ...@@ -1457,12 +1457,13 @@ String *Item_func_user::val_str(String *str)
{ {
THD *thd=current_thd; THD *thd=current_thd;
CHARSET_INFO *cs= default_charset(); CHARSET_INFO *cs= default_charset();
const char *host=thd->host ? thd->host : thd->ip ? thd->ip : ""; const char *host= thd->host_or_ip;
uint res_length;
// For system threads (e.g. replication SQL thread) user may be empty // For system threads (e.g. replication SQL thread) user may be empty
if (!thd->user) if (!thd->user)
return &empty_string; return &empty_string;
uint32 res_length=(strlen(thd->user)+strlen(host)+3) * cs->mbmaxlen; res_length= (strlen(thd->user)+strlen(host)+2) * cs->mbmaxlen;
// it is +3 , because 1 for each string and 1 for '@' sign
if (str->alloc(res_length)) if (str->alloc(res_length))
{ {
......
...@@ -1404,9 +1404,10 @@ static int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2) ...@@ -1404,9 +1404,10 @@ static int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... ) GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... )
*/ */
static int group_concat_key_cmp_with_distinct_and_order(void* arg, byte* key1, byte* key2) static int group_concat_key_cmp_with_distinct_and_order(void* arg,
byte* key1,
byte* key2)
{ {
Item_func_group_concat* item= (Item_func_group_concat*)arg;
if (!group_concat_key_cmp_with_distinct(arg,key1,key2)) if (!group_concat_key_cmp_with_distinct(arg,key1,key2))
return 0; return 0;
return(group_concat_key_cmp_with_order(arg,key1,key2)); return(group_concat_key_cmp_with_order(arg,key1,key2));
...@@ -1631,7 +1632,7 @@ void Item_func_group_concat::reset_field() ...@@ -1631,7 +1632,7 @@ void Item_func_group_concat::reset_field()
bool bool
Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
int i; /* for loop variable */ uint i; /* for loop variable */
if (!thd->allow_sum_func) if (!thd->allow_sum_func)
{ {
...@@ -1641,11 +1642,11 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -1641,11 +1642,11 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
thd->allow_sum_func= 0; thd->allow_sum_func= 0;
maybe_null= 0; maybe_null= 0;
for (uint ui= 0 ; ui < arg_count ; ui++) for (i= 0 ; i < arg_count ; i++)
{ {
if (args[ui]->fix_fields(thd, tables, args + ui) || args[ui]->check_cols(1)) if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1))
return 1; return 1;
maybe_null |= args[ui]->maybe_null; maybe_null |= args[i]->maybe_null;
} }
for (i= 0 ; i < arg_count_field ; i++) for (i= 0 ; i < arg_count_field ; i++)
{ {
......
...@@ -26,6 +26,8 @@ EXTRA_DIST = auto_increment.res auto_increment.tst \ ...@@ -26,6 +26,8 @@ EXTRA_DIST = auto_increment.res auto_increment.tst \
pmail.pl mail_to_db.pl table_types.pl \ pmail.pl mail_to_db.pl table_types.pl \
udf_test udf_test.res myisam-big-rows.tst udf_test udf_test.res myisam-big-rows.tst
noinst_PROGRAMS = insert_test select_test thread_test
# #
# C Test for 4.1 protocol # C Test for 4.1 protocol
# #
...@@ -36,6 +38,11 @@ noinst_PROGRAMS = client_test ...@@ -36,6 +38,11 @@ noinst_PROGRAMS = client_test
client_test_LDADD= $(LDADD) $(CXXLDFLAGS) client_test_LDADD= $(LDADD) $(CXXLDFLAGS)
client_test_SOURCES= client_test.c client_test_SOURCES= client_test.c
client_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) client_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
insert_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
select_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
thread_test.o: thread_test.c
$(COMPILE) -c @MT_INCLUDES@ $(INCLUDES) $<
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment