1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Compare commits

..

No commits in common. "master" and "2.5.1" have entirely different histories.

307 changed files with 17891 additions and 11050 deletions

4
cde/.gitignore vendored
View file

@ -52,7 +52,7 @@ programs/dtimsstart/dtimsstart
programs/dtlogin/dtchooser
programs/dtlogin/dtgreet
programs/dtlogin/dtlogin
programs/dtlogin/config/dtlogin
programs/dtlogin/config/pam/dtlogin
programs/dtmail/dtmail/dtmail
programs/dtmail/dtmailpr/dtmailpr
programs/dtpad/dtpad
@ -69,7 +69,7 @@ programs/dtsession/Dtsession
programs/dtsession/dtloadresources
programs/dtsession/dtsession
programs/dtsession/dtsession_res
programs/dtsession/config/dtsession
programs/dtsession/config/pam/dtsession
programs/dtspcd/dtspcd
programs/dtspcd/dtspcdenv
programs/dtsr/dtsrclean

View file

@ -6,50 +6,6 @@ use 'git log', or peruse the commit history at:
https://sourceforge.net/p/cdesktopenv/code/commit_browser
#######################################################################
### 2.5.2 (stable) 11/18/2023
This is mainly a bugfix release addressing various issues.
Shortlog:
Cy Schubert (1):
Fix build under LLVM15
Jon Trulson (9):
Apply various patches from Giacomo Comes <comes@naic.edu>
Patch from Giacomo Comes: rename ksh manpage to ksh-cde
Add DesktopNames=CDE to cde.desktop
pgadmin.dt: set icon from pgadmin to pgadmin3
dtfile/dterror.ds: fix script defines typo
dtksh: enable SHOPT_ECHOPRINT
dticon, dtpad, dtterm: fix session save issues (sprintf bogosity)
lib/DtHelp: strmove(): return memmove() result
.gitignore: add new locations of dtsession/dtlogin PAM files
Peter Howkins (3):
(Pascal Stumpf) Makefile.am change several places where ${prefix} should be $(CDE_INSTALLATION_TOP)
(Pascal Stumpf) CDE doesn't provide the ksh binary, don't install the manpage for it
(Pascal Stumpf) dtlogin: On OpenBSD start X as root (it drops privileges later)
hyousatsu (15):
DtTerm: fix a segfault by allocating a string dynamically.
dtwm: fix a title bar resizing issue.
dtwm: fix compiler warnings.
dtwm: add support for _NET_WM_VISIBLE_NAME and _NET_WM_VISIBLE_ICON_NAME.
dtwm: optimize EWMH processing.
localized: fix the character encoding errors in zh_TW.UTF-8.
dtwm: add a new feature -- window rename.
dtwm: optimize EWMH processing.
dtwm: support _NET_WM_STATE_ABOVE and _NET_WM_STATE_BELOW.
dtsession: change the maximum size of cover dialog to fullscreen.
dtlogin: use sessreg to manage utmp/wtmp.
dtwm: fix a segfault.
dtstyle: make the style manager recognize wheel mouse correctly.
tt: make the ttserver process events properly.
dtsession: fix a crash.
#######################################################################
### 2.5.1 (stable) 10/1/2022

View file

@ -1,7 +1,7 @@
dnl When changing the version below, also change the CDE_VERSION_* macros
dnl to match further below
AC_INIT([Common Desktop Environment],
[2.5.2],
[2.5.1],
[https://sourceforge.net/projects/cdesktopenv],
[cde],
[https://sourceforge.net/projects/cdesktopenv])
@ -13,7 +13,7 @@ dnl global CDE versioning
CDE_VERSION_MAJOR=2
CDE_VERSION_MINOR=5
CDE_VERSION_MICRO=2
CDE_VERSION_MICRO=1
dnl this is blank for a release, or contains an alpha character to indicate a
dnl dev release.
CDE_VERSION_DEV=
@ -177,6 +177,11 @@ AC_SUBST(LIBMMDB, '$(top_builddir)/lib/DtMmdb/libDtMmdb.la')
AC_SUBST(LIBHELP, '$(top_builddir)/lib/DtHelp/libDtHelp.la')
AC_SUBST(LIBCSA, '$(top_builddir)/lib/csa/libcsa.la')
AC_SUBST(LIBPAMSVC, '$(top_builddir)/lib/DtPamSvc/libDtPamSvc.la')
dnl we do not inclue the DtPamSvc library here as it is not needed
dnl for everything.
AC_SUBST(DTCLIENTLIBS, '$(LIBPRINT) $(LIBHELP) $(LIBWIDGET) $(LIBSVC) \
$(LIBTT) $(LIBXIN)')
@ -240,48 +245,6 @@ AC_ARG_ENABLE([xrender],
[disable_xrender="yes"], [disable_xrender=""]
)
dnl copied from xdm...
AC_ARG_WITH(utmp_file,
AS_HELP_STRING([--with-utmp-file=<pathname>],
[specify file to pass to sessreg -u for current logins])
AS_HELP_STRING([--without-utmp-file],
[specify passing "none" to sessreg -u to not record logins in utmp]),
[UTMP_FILE="$withval"])
if test "x$UTMP_FILE" = "xyes" ; then
UTMP_FILE=""
elif test "x$UTMP_FILE" = "xno" ; then
UTMP_FILE="none"
fi
AC_MSG_CHECKING([for path to file listing current logins for sessreg])
if test "x$UTMP_FILE" = "x" ; then
AC_MSG_RESULT([use sessreg default])
else
AC_MSG_RESULT([$UTMP_FILE])
fi
AM_CONDITIONAL(SET_UTMP_FILE, test x$UTMP_FILE != x)
AC_SUBST(UTMP_FILE)
AC_ARG_WITH(wtmp_file,
AS_HELP_STRING([--with-wtmp-file=<pathname>],
[specify file to pass to sessreg -w for login history])
AS_HELP_STRING([--without-wtmp-file],
[specify passing "none" to sessreg -w to not record logins in wtmp]),
[WTMP_FILE="$withval"])
if test "x$WTMP_FILE" = "xyes" ; then
WTMP_FILE=""
elif test "x$WTMP_FILE" = "xno" ; then
WTMP_FILE="none"
fi
AC_MSG_CHECKING([for path to file listing login history for sessreg])
if test "x$WTMP_FILE" = "x" ; then
AC_MSG_RESULT([use sessreg default])
else
AC_MSG_RESULT([$WTMP_FILE])
fi
AM_CONDITIONAL(SET_WTMP_FILE, test x$WTMP_FILE != x)
AC_SUBST(WTMP_FILE)
dnl hmmm...
RM="rm -f"
AC_SUBST(RM)
@ -378,10 +341,7 @@ AC_PATH_PROG(KSH, ksh)
if test -z "$ac_cv_path_KSH"; then
AC_PATH_PROG(KSH, ksh93)
if test -z "$ac_cv_path_KSH"; then
AC_PATH_PROG(KSH, mksh)
if test -z "$ac_cv_path_KSH"; then
MISSING_PROGS="[ksh or ksh93] ${MISSING_PROGS}"
fi
MISSING_PROGS="[ksh or ksh93] ${MISSING_PROGS}"
fi
fi
@ -436,10 +396,6 @@ AC_CHECK_PROGS(ONSGMLS, onsgmls)
if test -z "$ac_cv_prog_ONSGMLS"; then
MISSING_PROGS="ONSGMLS ${MISSING_PROGS}"
fi
AC_CHECK_PROGS(SESSREG, sessreg)
if test -z "$ac_cv_prog_SESSREG"; then
MISSING_PROGS="SESSREG ${MISSING_PROGS}"
fi
dnl Used to check if program 'tic' is available to install terminfo files
AC_CHECK_PROGS(TIC, tic, :)
@ -495,12 +451,6 @@ AC_CHECK_LIB(jpeg, jpeg_read_header, [JPEGLIB="-ljpeg"],
[${EXTRA_INCS} ${EXTRA_LIBS}])
AC_SUBST(JPEGLIB)
dnl lmdb
AC_CHECK_LIB(lmdb, mdb_version, [LMDBLIB="-llmdb"],
[AC_MSG_ERROR([liblmdb not found, please install it])],
[${EXTRA_INCS} ${EXTRA_LIBS}])
AC_SUBST(LMDBLIB)
dnl Setup XTOOLLIB - we do it in this specific order to avoid ordering
dnl issues
XTOOLLIB=""
@ -544,9 +494,7 @@ dnl Right now this only works on linux and netbsd (9.2 tested)
if test "$supports_pam" = "yes"
then
AC_CHECK_LIB(pam, pam_start,
[SOURCE_CPP_DEFINES="${SOURCE_CPP_DEFINES} -DHAS_PAM_LIBRARY";
PAMLIB="-lpam"])
AC_SUBST(PAMLIB)
[SOURCE_CPP_DEFINES="${SOURCE_CPP_DEFINES} -DHAS_PAM_LIBRARY"])
else
AC_CHECK_LIB(pam, NOTSUPPORTED)
fi
@ -617,6 +565,8 @@ lib/tt/bin/ttsession/Makefile
lib/DtSvc/Makefile
lib/DtPamSvc/Makefile
lib/DtSearch/Makefile
lib/DtSearch/raima/Makefile
@ -642,6 +592,7 @@ lib/DtMmdb/HardCopy/Makefile
lib/DtMmdb/StyleSheet/Makefile
lib/DtMmdb/api/Makefile
lib/DtMmdb/btree/Makefile
lib/DtMmdb/btree_berkeley/Makefile
lib/DtMmdb/compression/Makefile
lib/DtMmdb/diskhash/Makefile
lib/DtMmdb/dstr/Makefile

View file

@ -1,6 +1,5 @@
[Desktop Entry]
Name=CDE
DesktopNames=CDE
Comment=Use this session to boot into the Common Desktop Environment
Keywords=Common Desktop Environment
Exec=/usr/dt/bin/Xsession

View file

@ -1,16 +0,0 @@
#!/bin/sh
# PROVIDE: dtlogin
# REQUIRE: DAEMON LOGIN wscons
# KEYWORD: shutdown
$_rc_subr_loaded . /etc/rc.subr
name="dtlogin"
rcvar=$name
command="/usr/dt/bin/${name}"
command_args="-daemon"
pidfile=/var/dt/Xpid
extra_commands=""
load_rc_config $name
run_rc_command "$1"

View file

@ -1,11 +0,0 @@
daemon="/usr/dt/bin/rpc.cmsd &"
. /etc/rc.d/rc.subr
pexp="rpc.cmsd: ${daemon}${daemon_flags:+ ${daemon_flags}} \[listener\].*"
rc_reload() {
${daemon} ${daemon_flags} -t && pkill -HUP -xf "${pexp}"
}
rc_cmd $1

View file

@ -1,25 +0,0 @@
#!/bin/ksh
daemon="/usr/dt/bin/dtlogin"
. /etc/rc.d/rc.subr
rc_reload=NO
if [ -n "${INRC}" ]; then
# on boot: make sure we don't hang in _rc_wait
_rc_wait() {
return 0
}
# on boot: wait for ttys to be initialized
rc_start() {
( local i=0
while ! pgrep -qf "^/usr/libexec/getty "; do
sleep 1
[ $((i++)) -ge 10 ] && return 1
done
${rcexec} "${daemon} ${daemon_flags}" ) &
}
fi
rc_cmd $1

View file

@ -1,11 +0,0 @@
[Unit]
Description=CDE login service
Documentation=man:dtlogin(1)
Requires=rpcbind.service
After=systemd-user-sessions.service
[Service]
ExecStart=/usr/dt/bin/dtlogin -nodaemon
[Install]
Alias=display-manager.service

View file

@ -21,7 +21,3 @@ endif
if JAPANESE
SUBDIRS += ja_JP.UTF-8
endif
install-data-hook:
$(RM) $(DESTDIR)$(CDE_INSTALLATION_TOP)/man
cd $(DESTDIR)$(CDE_INSTALLATION_TOP)/ && $(LN_S) $(mandir) man

View file

@ -700,39 +700,6 @@ indem im Dialogfenster 'Neustart' des Umgebungsmanagers die Option 'Standardsitz
festlegen' ausgewählt wird.</para>
<!-- MODULE SEConfirmLogoutWithChoiceDE SElogch.DEa -->
</sect2>
<Sect2 Id="WMWindowRenameDialogDE">
<Title>Dialogfeld zum Umbenennen von Fenstern</Title>
<Para><Anchor Id="WindowRename">
</Para>
<Para>
Geben Sie den neuen Namen in das Textfeld ein (lassen Sie es leer, um
den Standardfenstertitel wiederherzustellen).
</Para>
<VariableList>
<VarListEntry>
<Term>OK</Term>
<ListItem>
<Para>
Benennen Sie das Fenster um und schließen Sie den Umbenennen Dialog.
</Para>
</ListItem>
</VarListEntry>
<VarListEntry>
<Term>Abbrechen</Term>
<ListItem>
<Para>
Brechen Sie das Umbenennen ab und schließen Sie den Umbenennen Dialog.
</Para>
</ListItem>
</VarListEntry>
<VarListEntry>
<Term>Hilfe</Term>
<ListItem>
<Para>Zeigt dieses Hilfethema an.</Para>
</ListItem>
</VarListEntry>
</VariableList>
</Sect2>
</sect1>
<sect1 id="ConfirmSessionCreateDE">
<title>Bestätigung der Sitzungserstellung<anchor id="ConfirmSessionCreation"></title>

View file

@ -32,7 +32,7 @@ Inc.--><refsynopsisdiv>
</cmdsynopsis>
</refsynopsisdiv><refsect1>
<title>DESCRIPTION</title>
<para>The <command>dtksh</command> utility is a version of the <![ %CDE.C.XO; [ <command>ksh-cde</command> utility (defined in the &str-ZC;) ]]><![ %CDE.C.CDE; [KornShell ]]>extended
<para>The <command>dtksh</command> utility is a version of the <![ %CDE.C.XO; [ <command>sh</command> utility (defined in the &str-ZC;) ]]><![ %CDE.C.CDE; [KornShell ]]>extended
to support:</para>
<itemizedlist>
<listitem>
@ -68,10 +68,10 @@ using the &str-XZ; customization tool</para>
</itemizedlist>
</refsect1><refsect1>
<title>OPTIONS</title>
<para>See <![ %CDE.C.CDE; [<command>ksh-cde</command>(1). ]]><![ %CDE.C.XO; [ <command>ksh-cde</command> in the &str-ZC;. ]]></para>
<para>See <![ %CDE.C.CDE; [<command>sh</command>(1). ]]><![ %CDE.C.XO; [ <command>sh</command> in the &str-ZC;. ]]></para>
</refsect1><refsect1>
<title>OPERANDS</title>
<para>See <![ %CDE.C.CDE; [<command>ksh-cde</command>(1). ]]><![ %CDE.C.XO; [ <command>ksh-cde</command> in the &str-ZC;. ]]></para>
<para>See <![ %CDE.C.CDE; [<command>sh</command>(1). ]]><![ %CDE.C.XO; [ <command>sh</command> in the &str-ZC;. ]]></para>
</refsect1><refsect1>
<title>RESOURCES</title>
<para>The <command>dtksh</command> interpreter has no relevant resources outside
@ -80,14 +80,14 @@ a <command>dtksh</command> script. Refer to the manual page of the relevant
widget for information on the resources that apply to that widget.</para>
</refsect1><refsect1>
<title>STDIN</title>
<para>See <![ %CDE.C.CDE; [<command>ksh-cde</command>(1). ]]><![ %CDE.C.XO; [ <command>ksh-cde</command> in the &str-ZC;. ]]></para>
<para>See <![ %CDE.C.CDE; [<command>sh</command>(1). ]]><![ %CDE.C.XO; [ <command>sh</command> in the &str-ZC;. ]]></para>
</refsect1><refsect1>
<title>INPUT FILES</title>
<para>See <![ %CDE.C.CDE; [<command>ksh-cde</command>(1). ]]><![ %CDE.C.XO; [ <command>ksh-cde</command> in the &str-ZC;. ]]></para>
<para>See <![ %CDE.C.CDE; [<command>sh</command>(1). ]]><![ %CDE.C.XO; [ <command>sh</command> in the &str-ZC;. ]]></para>
</refsect1><refsect1>
<title>ENVIRONMENT VARIABLES</title>
<para>The following information describes the environment variables that <command>dtksh</command> uses that are in addition to those documented in the manual
page for the <command>ksh-cde</command> command language interpreter.</para>
page for the <command>sh</command> command language interpreter.</para>
<refsect2>
<title>Immediate Return Value (-)</title>
<para>Many of the category 3 commands (as described in <![ %CDE.C.CDE; [the <literal>Return Values From Built-in Commands</literal> section) ]]><![ %CDE.C.XO; [<xref
@ -406,18 +406,18 @@ to remove the input source using <command>XtRemoveInput</command>.</para>
<para>Default.</para>
</refsect1><refsect1>
<title>STDOUT</title>
<para>See <![ %CDE.C.CDE; [<command>ksh-cde</command>(1). ]]><![ %CDE.C.XO; [ <command>ksh-cde</command> in the &str-ZC;. ]]></para>
<para>See <![ %CDE.C.CDE; [<command>sh</command>(1). ]]><![ %CDE.C.XO; [ <command>sh</command> in the &str-ZC;. ]]></para>
</refsect1><refsect1>
<title>STDERR</title>
<para>See <![ %CDE.C.CDE; [<command>ksh-cde</command>(1). ]]><![ %CDE.C.XO; [ <command>ksh-cde</command> in the &str-ZC;. ]]></para>
<para>See <![ %CDE.C.CDE; [<command>sh</command>(1). ]]><![ %CDE.C.XO; [ <command>sh</command> in the &str-ZC;. ]]></para>
</refsect1><refsect1>
<title>OUTPUT FILES</title>
<para>None.</para>
</refsect1><refsect1>
<title>EXTENDED DESCRIPTION</title>
<para>The capabilities described here are extensions to those of the <command>ksh-cde</command> command language interpreter. See <![ %CDE.C.CDE; [ <command>ksh-cde</command>(1). ]]><![ %CDE.C.XO; [<command>ksh-cde</command> in the &str-ZC;. ]]>The
<para>The capabilities described here are extensions to those of the <command>sh</command> command language interpreter. See <![ %CDE.C.CDE; [ <command>sh</command>(1). ]]><![ %CDE.C.XO; [<command>sh</command> in the &str-ZC;. ]]>The
following subsections give a synopsis of each of the built-in commands added
by <command>dtksh</command> to <command>ksh-cde</command>. In general, argument
by <command>dtksh</command> to <command>sh</command>. In general, argument
ordering and types are the same as for corresponding C procedures, with exceptions
noted. For more detail on the functionality and arguments of a command, see
the standard documentation for the corresponding X11, Xt, Motif or Desktop
@ -2970,10 +2970,10 @@ the resource name.</para>
</refsect2>
</refsect1><refsect1>
<title>EXIT STATUS</title>
<para>See <![ %CDE.C.CDE; [<command>ksh-cde</command>(1). ]]><![ %CDE.C.XO; [ <command>ksh-cde</command> in the &str-ZC;. ]]></para>
<para>See <![ %CDE.C.CDE; [<command>sh</command>(1). ]]><![ %CDE.C.XO; [ <command>sh</command> in the &str-ZC;. ]]></para>
</refsect1><refsect1>
<title>CONSEQUENCES OF ERRORS</title>
<para>See <![ %CDE.C.CDE; [<command>ksh-cde</command>(1). ]]><![ %CDE.C.XO; [ <command>ksh-cde</command> in the &str-ZC;. ]]></para>
<para>See <![ %CDE.C.CDE; [<command>sh</command>(1). ]]><![ %CDE.C.XO; [ <command>sh</command> in the &str-ZC;. ]]></para>
</refsect1><refsect1>
<title>APPLICATION USAGE</title>
<refsect2>
@ -3229,7 +3229,7 @@ labelString:$(catgets $MSG_CAT_ID 1 3 "Cancel")
catclose $MSG_CAT_ID</programlisting>
</informalexample>
<para>The file descriptor returned by <command>catopen</command> must be closed
using <command>catclose</command>, and not using the <command>ksh-cde</command> <command>exec</command> command.</para>
using <command>catclose</command>, and not using the <command>sh</command> <command>exec</command> command.</para>
</refsect2>
<refsect2>
<title>Using the dtksh Utility to Access X Drawing Functions</title>
@ -3322,6 +3322,6 @@ XtOverrideTranslations $BUTTON2
<title>EXAMPLES</title>
<para>None.</para>
</refsect1><refsect1>
<title>SEE ALSO<?Pub Caret></title><![ %CDE.C.CDE; [<para><command>ksh-cde</command>(1).</para>]]><![ %CDE.C.XO; [<para><command>ksh-cde</command> in the &str-ZC;.</para>]]></refsect1></refentry>
<title>SEE ALSO<?Pub Caret></title><![ %CDE.C.CDE; [<para><command>sh</command>(1).</para>]]><![ %CDE.C.XO; [<para><command>sh</command> in the &str-ZC;.</para>]]></refsect1></refentry>
<!--fickle 1.12 mancsf-to-docbook 1.2 08/07/95 23:40:24-->
<?Pub *0000198752>

View file

@ -814,35 +814,6 @@ to keep returning. Save a home session by choosing
Set Home Session in Style Manager's Startup dialog box.</Para>
<!-- MODULE SEConfirmLogoutWithChoiceDE SElogch.DEa -->
</Sect2>
<Sect2 Id="WMWindowRenameDialogDE">
<Title>Window Rename Dialog</Title>
<Para><Anchor Id="WindowRename">
</Para>
<Para>
Type the new name in the text field (leave it blank to restore the
default window title).
</Para>
<VariableList>
<VarListEntry>
<Term>OK</Term>
<ListItem>
<Para>Rename the window and close the rename dialog.</Para>
</ListItem>
</VarListEntry>
<VarListEntry>
<Term>Cancel</Term>
<ListItem>
<Para>Cancel renaming and close the rename dialog.</Para>
</ListItem>
</VarListEntry>
<VarListEntry>
<Term>Help</Term>
<ListItem>
<Para>Displays this help topic.</Para>
</ListItem>
</VarListEntry>
</VariableList>
</Sect2>
</Sect1>
<Sect1 Id="ConfirmSessionCreateDE">

View file

@ -8,7 +8,7 @@ DBTOMAN = $(top_srcdir)/programs/dtdocbook/doc_utils/dtdocbook2man $(LANG)
# first, the man pages broken down by sections
MANSEC1 = man1/tttrace.1 man1/tttar.1 man1/ttsession.1 man1/ttrmdir.1 \
man1/ttrm.1 man1/ttmv.1 man1/ttcp.1 man1/tt_type_comp.1 \
man1/ksh-cde.1 man1/huffcode.1 man1/dtwm.1 man1/dtudcfonted.1 \
man1/ksh.1 man1/huffcode.1 man1/dtwm.1 man1/dtudcfonted.1 \
man1/dtudcexch.1 man1/dttypes.1 man1/dtterm.1 man1/dtstyle.1 \
man1/dtsrload.1 man1/dtsrkdump.1 man1/dtsrindex.1 man1/dtsrhan.1 \
man1/dtsrdbrec.1 man1/dtsrcreate.1 man1/dtsession_res.1 \
@ -523,7 +523,7 @@ man1/dtwm.1: ../guides/man/man1_dt/wm.sgm $(MANDEPS)
man1/huffcode.1: ../guides/man/man1_dt/huffcode.sgm $(MANDEPS)
$(DBTOMAN) cdedecl.sgm $< $@
man1/ksh-cde.1: ../guides/man/man1/ksh93.sgm $(MANDEPS)
man1/ksh.1: ../guides/man/man1/ksh93.sgm $(MANDEPS)
$(DBTOMAN) cdedecl.sgm $< $@
man1/tt_type_comp.1: ../guides/man/man1/tt_typ_c.sgm $(MANDEPS)

View file

@ -670,41 +670,6 @@ Establecer sesión de inicio en el cuadro de diálogo Arranque
del Gestor de estilos.</para>
<!-- MODULE SEConfirmLogoutWithChoiceDE SElogch.DEa -->
</sect2>
<Sect2 Id="WMWindowRenameDialogDE">
<Title>Cuadro de diálogo Cambiar nombre de ventana</Title>
<Para><Anchor Id="WindowRename">
</Para>
<Para>
Escriba el nuevo nombre en el campo de texto (déjalo en blanco para
restaurar el título de ventana predeterminado).
</Para>
<VariableList>
<VarListEntry>
<Term>OK</Term>
<ListItem>
<Para>
Cambie el nombre de la ventana y cierre el cuadro de diálogo de
cambio de nombre.
</Para>
</ListItem>
</VarListEntry>
<VarListEntry>
<Term>Cancelar</Term>
<ListItem>
<Para>
Cancele el cambio de nombre y cierre el cuadro de diálogo de cambio
de nombre.
</Para>
</ListItem>
</VarListEntry>
<VarListEntry>
<Term>Ayuda</Term>
<ListItem>
<Para>Muestra este tema de ayuda.</Para>
</ListItem>
</VarListEntry>
</VariableList>
</Sect2>
</sect1>
<sect1 id="ConfirmSessionCreateDE">
<title>Confirmación de la creación de una sesión <anchor

View file

@ -731,40 +731,6 @@ session initiale dans la boîte de dialogue Lancement du Gestionnaire
de configuration.</para>
<!-- MODULE SEConfirmLogoutWithChoiceDE SElogch.DEa -->
</sect2>
<Sect2 Id="WMWindowRenameDialogDE">
<Title>Boîte de dialogue Renommer la fenêtre</Title>
<Para><Anchor Id="WindowRename">
</Para>
<Para>
Tapez le nouveau nom dans le champ de texte (laissez-le vide pour
restaurer le titre de fenêtre par défaut).
</Para>
<VariableList>
<VarListEntry>
<Term>OK</Term>
<ListItem>
<Para>
Renommez la fenêtre et fermez la boîte de dialogue de renommage.
</Para>
</ListItem>
</VarListEntry>
<VarListEntry>
<Term>Annuler</Term>
<ListItem>
<Para>
Annuler le changement de nom et fermez la boîte de dialogue de
changement de nom.
</Para>
</ListItem>
</VarListEntry>
<VarListEntry>
<Term>Aide</Term>
<ListItem>
<Para>Affiche l'aide.</Para>
</ListItem>
</VarListEntry>
</VariableList>
</Sect2>
</sect1>
<sect1 id="ConfirmSessionCreateDE">
<title>Confirmation de création de session<anchor id="ConfirmSessionCreation"></title>

View file

@ -664,40 +664,6 @@ scegliere Impostare sessione iniziale nel riquadro di dialogo Avvio della
Gestione degli stili.</para>
<!-- MODULE SEConfirmLogoutWithChoiceDE SElogch.DEa -->
</sect2>
<Sect2 Id="WMWindowRenameDialogDE">
<Title>Finestra di dialogo Rinomina finestra</Title>
<Para><Anchor Id="WindowRename">
</Para>
<Para>
Digitare il nuovo nome nel campo di testo (lasciarlo vuoto per
ripristinare il titolo predefinito della finestra).
</Para>
<VariableList>
<VarListEntry>
<Term>OK</Term>
<ListItem>
<Para>
Rinominare la finestra e chiudere la finestra di dialogo Rinomina.
</Para>
</ListItem>
</VarListEntry>
<VarListEntry>
<Term>Annullare</Term>
<ListItem>
<Para>
Annulla la ridenominazione e chiudi la finestra di dialogo per la
ridenominazione.
</Para>
</ListItem>
</VarListEntry>
<VarListEntry>
<Term>Aiuto</Term>
<ListItem>
<Para>Visualizza queste informazioni di aiuto.</Para>
</ListItem>
</VarListEntry>
</VariableList>
</Sect2>
</sect1>
<sect1 id="confirmsessioncreatede">
<title>Conferma della creazione di una sessione<anchor id="confirmsessioncreation"></title>

View file

@ -764,35 +764,6 @@
[スタイル・マネージャの起動] ダイアログ・ボックスの [ホームセッションを設定] を選択して、ホーム・セッションを保存してください。</Para>
<!-- MODULE SEConfirmLogoutWithChoiceDE SElogch.DEa -->
</Sect2>
<Sect2 Id="WMWindowRenameDialogDE">
<Title>ウィンドウの名前の変更・ダイアログ</Title>
<Para><Anchor Id="WindowRename">
</Para>
<Para>
テキストフィールドに新しい名前を入力します(空白のままにすると、
デフォルトのウィンドウ タイトルが復元されます)。
</Para>
<VariableList>
<VarListEntry>
<Term>了解</Term>
<ListItem>
<Para>ウィンドウの名前を変更し、名前の変更ダイアログを閉じます。</Para>
</ListItem>
</VarListEntry>
<VarListEntry>
<Term>取消し</Term>
<ListItem>
<Para>名前の変更をキャンセルし、名前の変更ダイアログを閉じます。</Para>
</ListItem>
</VarListEntry>
<VarListEntry>
<Term>ヘルプ</Term>
<ListItem>
<Para>ヘルプ・トピックを表示します。</Para>
</ListItem>
</VarListEntry>
</VariableList>
</Sect2>
</Sect1>
<Sect1 Id="ConfirmSessionCreateDE">

58
cde/include/Dt/PamSvc.h Normal file
View file

@ -0,0 +1,58 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: pam_svc.h /main/3 1996/10/30 11:13:40 drk $ */
/*******************************************************************************
**
** "@(#)pam_svc.h 1.4 95/09/12
**
** Copyright 1993, 1994, 1995 Sun Microsystems, Inc. All rights reserved.
**
** This file contains header info related to use of PAM
** (Pluggable Authentication Module) library.
**
*******************************************************************************/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _DT_PAM_SVC_H
#define _DT_PAM_SVC_H
#include <sys/types.h>
#define DT_BAD_GID 29 /* Invalid Group ID */
#define DT_INITGROUP_FAIL 30 /* group IDs init failed */
#define DT_BAD_UID 31 /* Invaid User ID */
/*
* External procedure declarations
*/
extern int _DtAuthentication(char*, char*, char*, char*, char*);
extern int _DtAccounting(char*, char*, char[], char*, char*, pid_t, int, int);
extern int _DtSetCred(char*, char *, uid_t, gid_t);
#endif /* _DT_PAM_SVC_H */

View file

@ -189,10 +189,10 @@ int d_cmtype(int, int *, int); /* cmtype.c */
int d_connect(int, int); /* connect.c */
int d_cotype(int, int *, int); /* cotype.c */
int d_crget(DB_ADDR *, int); /* crget.c */
int d_crread(long, void *, int); /* crread.c */
int d_crread(long, char *, int); /* crread.c */
int d_crset(DB_ADDR *, int); /* crset.c */
int d_crtype(int *, int); /* crtype.c */
int d_crwrite(long, void *, int); /* crwrite.c */
int d_crwrite(long, char *, int); /* crwrite.c */
int d_csmget(int, DB_ADDR *, int); /* csmget.c */
int d_csmread(int, long, char *, int);
/* csmread.c */
@ -217,7 +217,7 @@ int d_recnext(int); /* recnext.c */
int d_recprev(int); /* recprev.c */
int d_destroy(const char *); /* destroy.c */
int d_discon(int, int); /* discon.c */
int d_fillnew(int, const void *, int); /* fillnew.c */
int d_fillnew(int, const char *, int); /* fillnew.c */
int d_findco(int, int); /* findco.c */
int d_findfm(int, int); /* findfm.c */
int d_findlm(int, int); /* findlm.c */
@ -258,9 +258,9 @@ int d_reclast(int, int); /* reclast.c */
int d_reclock(int, char *, int); /* dblfcns.c */
int d_reclstat(int, char *, int); /* dblfcns.c */
int d_recover(const char *); /* recover.c */
int d_recread(void *, int); /* recread.c */
int d_recread(char *, int); /* recread.c */
int d_recset(int, int); /* recset.c */
int d_recwrite(const void *, int); /* recwrite.c */
int d_recwrite(const char *, int); /* recwrite.c */
int d_renfile(const char *dbn, FILE_NO fno, const char *fnm); /* renfile.c */
int d_retries(int); /* dblfcns.c */
int d_rlbclr(void); /* dblfcns.c */

View file

@ -28,4 +28,7 @@ nobase_include_HEADERS = Dt/Editor.h \
Dt/Search.h \
Dt/Mmdb.h \
Dt/DtXinerama.h \
Dt/SvcPam.h
Dt/PamSvc.h

View file

@ -59,8 +59,6 @@
extern int errno;
#endif
extern char *_DtHelpGetLocale(void);
/*
* Canvas Engine includes
*/

View file

@ -4366,7 +4366,7 @@ FindSnbEntry(
* but safe for overlapping regions.
*/
static void *strmove(void *dest, const void *src) {
return memmove(dest, src, strlen(src) + 1);
memmove(dest, src, strlen(src) + 1);
}
/******************************************************************************

View file

@ -4,6 +4,7 @@ SUBDIRS = HardCopy \
StyleSheet \
api \
btree \
btree_berkeley \
compression \
diskhash \
dstr \
@ -28,6 +29,7 @@ libDtMmdb_la_LIBADD = HardCopy/libHardCopy.la \
StyleSheet/libStyleSheet.la \
api/libapi.la \
btree/libbtree.la \
btree_berkeley/libbtree_berkeley.la \
compression/libcompression.la \
diskhash/libdiskhash.la \
dstr/libdstr.la \

View file

@ -4,4 +4,4 @@ noinst_LTLIBRARIES = libbtree.la
libbtree_la_CXXFLAGS = -I..
libbtree_la_SOURCES = btree.C
libbtree_la_SOURCES = mmdb_btree.C

View file

@ -48,45 +48,44 @@
*/
#include "btree/btree.h"
#include "btree/mmdb_btree.h"
btree::btree(const char* store_name)
{
int err;
MDB_txn *txn;
// let the package figure out all these parameters
btree_info.flags = 0;
btree_info.cachesize = 0;
btree_info.maxkeypage = 0;
btree_info.minkeypage = 0;
btree_info.psize = 0;
btree_info.compare = NULL;
btree_info.prefix = NULL;
btree_info.lorder = 0;
key_DBT.mv_data = 0;
key_DBT.mv_size = 0;
key_DBT.data = 0;
key_DBT.size = 0;
if ((err = mdb_env_create(&btree_env)))
throw(stringException(mdb_strerror(err)));
int mode = O_CREAT|O_RDWR;
if ((err = mdb_env_open(btree_env, store_name, MDB_NOSUBDIR | MDB_NOSYNC,
0640)))
throw(stringException(mdb_strerror(err)));
//btree_DB = dbopen(store_name, mode, 0640, DB_BTREE, &btree_info);
btree_DB = dbopen(store_name, mode, 0640, DB_BTREE, NULL);
txn = txn_begin();
if ((err = mdb_dbi_open(txn, NULL, 0, &btree_DB))) {
mdb_txn_abort(txn);
throw(stringException(mdb_strerror(err)));
}
txn_commit(txn);
if ( btree_DB == 0 )
throw(stringException("btree dbopen failed"));
}
btree::~btree()
{
int err;
if ((err = mdb_env_sync(btree_env, 0))) {
cerr << mdb_strerror(err);
if ( btree_DB->sync(btree_DB, 0) == RET_ERROR ) {
cerr << "btree sync failed";
std::exit(1);
}
mdb_dbi_close(btree_env, btree_DB);
mdb_env_close(btree_env);
if ( btree_DB->close(btree_DB) == RET_ERROR ) {
cerr << "btree close failed";
std::exit(1);
}
}
void btree::clean()
@ -98,13 +97,13 @@ void btree::data_t_2_DBT(data_t& w)
{
switch (w.flag) {
case data_t::INT:
key_DBT.mv_data = &w.key.int_key;
key_DBT.mv_size = sizeof(w.key.int_key);
key_DBT.data = &w.key.int_key;
key_DBT.size = sizeof(w.key.int_key);
break;
case data_t::STRING:
key_DBT.mv_data = w.key.str_key;
key_DBT.mv_size = strlen(w.key.str_key);
key_DBT.data = w.key.str_key;
key_DBT.size = strlen(w.key.str_key);
break;
case data_t::VOID:
@ -114,78 +113,74 @@ void btree::data_t_2_DBT(data_t& w)
Boolean btree::insert(data_t& w)
{
int err;
MDB_txn *txn;
data_t_2_DBT(w);
MDB_val data_DBT;
data_DBT.mv_data = &w.dt;
data_DBT.mv_size = sizeof(w.dt);
DBT data_DBT;
data_DBT.data = &w.dt;
data_DBT.size = sizeof(w.dt);
txn = txn_begin();
//int status = btree_DB->put(btree_DB, &key_DBT, &data_DBT, R_NOOVERWRITE);
int status = btree_DB->put(btree_DB, &key_DBT, &data_DBT, 0);
err = mdb_put(txn, btree_DB, &key_DBT, &data_DBT, 0);
switch (status) {
case RET_ERROR:
throw(stringException("btree put failed"));
break;
if (err && err != MDB_MAP_FULL && err != MDB_TXN_FULL) {
mdb_txn_abort(txn);
throw(stringException(mdb_strerror(err)));
case RET_SPECIAL:
throw(stringException("btree put: dup key"));
break;
case RET_SUCCESS:
return true;
}
txn_commit(txn);
if (err) {
cerr << mdb_strerror(err);
return false;
}
return true;
return false;
}
Boolean btree::remove(data_t& w)
{
int err;
MDB_txn *txn;
data_t_2_DBT(w);
txn = txn_begin();
int status = btree_DB->del(btree_DB, &key_DBT, 0);
if ((err = mdb_del(txn, btree_DB, &key_DBT, NULL))) {
mdb_txn_abort(txn);
throw(stringException(mdb_strerror(err)));
switch (status) {
case RET_ERROR:
throw(stringException("btree delete failed"));
break;
case RET_SPECIAL:
case RET_SUCCESS:
return true;
}
txn_commit(txn);
return true;
return false;
}
Boolean btree::member(data_t& w)
Boolean btree::member(data_t& w)
{
int err;
MDB_txn *txn;
data_t_2_DBT(w);
MDB_val data_DBT;
DBT data_DBT;
txn = txn_begin(MDB_RDONLY);
int status = btree_DB->get(btree_DB, &key_DBT, &data_DBT, 0);
err = mdb_get(txn, btree_DB, &key_DBT, &data_DBT);
switch (status) {
case RET_ERROR:
throw(stringException("btree get failed"));
break;
mdb_txn_abort(txn);
case RET_SPECIAL:
return false;
if (err) {
if (err != MDB_NOTFOUND) throw(stringException(mdb_strerror(err)));
return false;
case RET_SUCCESS:
if ( data_DBT.size != sizeof(w.dt) )
throw(stringException("btree get: tree corrupted"));
memcpy((char*)&w.dt, data_DBT.data, data_DBT.size);
return true;
}
if (data_DBT.mv_size != sizeof(w.dt))
throw(stringException("btree get: tree corrupted"));
memcpy((char*)&w.dt, data_DBT.mv_data, data_DBT.mv_size);
return true;
return false;
}
ostream& btree::asciiOut(ostream& out)
@ -198,19 +193,3 @@ istream& btree::asciiIn(istream& in)
return in;
}
MDB_txn *btree::txn_begin(unsigned int flags) {
int err;
MDB_txn *txn;
if ((err = mdb_txn_begin(btree_env, NULL, flags, &txn)))
throw(stringException(mdb_strerror(err)));
return txn;
}
void btree::txn_commit(MDB_txn *txn) {
int err;
if ((err = mdb_txn_commit(txn)))
throw(stringException(mdb_strerror(err)));
}

View file

@ -69,9 +69,9 @@
#endif
#include <cstdlib>
#include <lmdb.h>
#include "dstr/index_agent.h"
#include "btree_berkeley/db.h"
class btree : public index_agent
@ -91,14 +91,12 @@ public:
istream& asciiIn(istream& in);
protected:
MDB_val key_DBT;
MDB_dbi btree_DB;
MDB_env *btree_env;
DBT key_DBT;
DB* btree_DB;
BTREEINFO btree_info;
protected:
void data_t_2_DBT(data_t& w);
MDB_txn *txn_begin(unsigned int flags = 0);
void txn_commit(MDB_txn *txn);
};
#endif

View file

@ -0,0 +1,16 @@
MAINTAINERCLEANFILES = Makefile.in
noinst_LTLIBRARIES = libbtree_berkeley.la
libbtree_berkeley_la_CFLAGS = -DMEMMOVE -I..
libbtree_berkeley_la_SOURCES = bt_close.c bt_conv.c bt_debug.c bt_delete.c \
bt_get.c bt_open.c bt_overflow.c bt_page.c \
bt_put.c bt_search.c bt_seq.c bt_split.c \
bt_stack.c bt_utils.c mktemp.c \
realloc.c snprintf.c mpool.c db.c
if AIX
else
libbtree_berkeley_la_SOURCES += memmove.c
endif

View file

@ -0,0 +1,227 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: bt_close.c /main/4 1996/06/11 17:12:14 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_close.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <db.h>
#include "btree.h"
static int bt_meta __P((BTREE *));
/*
* BT_CLOSE -- Close a btree.
*
* Parameters:
* dbp: pointer to access method
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__bt_close(DB *dbp)
{
BTREE *t;
int fd;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
/*
* Delete any already deleted record that we've been saving
* because the cursor pointed to it.
*/
if (ISSET(t, B_DELCRSR) && __bt_crsrdel(t, &t->bt_bcursor))
return (RET_ERROR);
if (__bt_sync(dbp, 0) == RET_ERROR)
return (RET_ERROR);
if (mpool_close(t->bt_mp) == RET_ERROR)
return (RET_ERROR);
if (t->bt_stack)
free(t->bt_stack);
if (t->bt_kbuf)
free(t->bt_kbuf);
if (t->bt_dbuf)
free(t->bt_dbuf);
fd = t->bt_fd;
free(t);
free(dbp);
return (close(fd) ? RET_ERROR : RET_SUCCESS);
}
/*
* BT_SYNC -- sync the btree to disk.
*
* Parameters:
* dbp: pointer to access method
*
* Returns:
* RET_SUCCESS, RET_ERROR.
*/
int
__bt_sync(const DB *dbp, u_int flags)
{
BTREE *t;
int status;
PAGE *h;
void *p = NULL;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
/* Sync doesn't currently take any flags. */
if (flags != 0) {
errno = EINVAL;
return (RET_ERROR);
}
if (ISSET(t, B_INMEM | B_RDONLY) || !ISSET(t, B_MODIFIED))
return (RET_SUCCESS);
if (ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR)
return (RET_ERROR);
/*
* Nastiness. If the cursor has been marked for deletion, but not
* actually deleted, we have to make a copy of the page, delete the
* key/data item, sync the file, and then restore the original page
* contents.
*/
if (ISSET(t, B_DELCRSR)) {
if ((p = (void*)malloc(t->bt_psize)) == NULL)
return (RET_ERROR);
if ((h = mpool_get(t->bt_mp, t->bt_bcursor.pgno, 0)) == NULL) {
free(p);
return (RET_ERROR);
}
memmove(p, h, t->bt_psize);
if ((status =
__bt_dleaf(t, h, t->bt_bcursor.index)) == RET_ERROR)
goto ecrsr;
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
}
if ((status = mpool_sync(t->bt_mp)) == RET_SUCCESS)
CLR(t, B_MODIFIED);
ecrsr: if (ISSET(t, B_DELCRSR)) {
if ((h = mpool_get(t->bt_mp, t->bt_bcursor.pgno, 0)) == NULL) {
free(p);
return (RET_ERROR);
}
memmove(h, p, t->bt_psize);
free(p);
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
}
return (status);
}
/*
* BT_META -- write the tree meta data to disk.
*
* Parameters:
* t: tree
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
static int
bt_meta(BTREE *t)
{
BTMETA m;
void *p;
if ((p = mpool_get(t->bt_mp, P_META, 0)) == NULL)
return (RET_ERROR);
/* Fill in metadata. */
m.m_magic = BTREEMAGIC;
m.m_version = BTREEVERSION;
m.m_psize = t->bt_psize;
m.m_free = t->bt_free;
m.m_nrecs = t->bt_nrecs;
m.m_flags = t->bt_flags & SAVEMETA;
memmove(p, &m, sizeof(BTMETA));
mpool_put(t->bt_mp, p, MPOOL_DIRTY);
return (RET_SUCCESS);
}

View file

@ -0,0 +1,237 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: bt_conv.c /main/3 1996/06/11 17:12:19 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_conv.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <stdio.h>
#include <db.h>
#include "btree.h"
static void mswap __P((PAGE *));
/*
* __BT_BPGIN, __BT_BPGOUT --
* Convert host-specific number layout to/from the host-independent
* format stored on disk.
*
* Parameters:
* t: tree
* pg: page number
* h: page to convert
*/
void
__bt_pgin(void *t, pgno_t pg, void *pp)
{
PAGE *h;
int i, top;
u_char flags;
char *p;
if (!ISSET(((BTREE *)t), B_NEEDSWAP))
return;
if (pg == P_META) {
mswap(pp);
return;
}
h = pp;
BLSWAP(h->pgno);
BLSWAP(h->prevpg);
BLSWAP(h->nextpg);
BLSWAP(h->flags);
BSSWAP(h->lower);
BSSWAP(h->upper);
top = NEXTINDEX(h);
if ((h->flags & P_TYPE) == P_BINTERNAL)
for (i = 0; i < top; i++) {
BSSWAP(h->linp[i]);
p = (char *)GETBINTERNAL(h, i);
BLPSWAP(p);
p += sizeof(size_t);
BLPSWAP(p);
p += sizeof(pgno_t);
if (*(u_char *)p & P_BIGKEY) {
p += sizeof(u_char);
BLPSWAP(p);
p += sizeof(pgno_t);
BLPSWAP(p);
}
}
else if ((h->flags & P_TYPE) == P_BLEAF)
for (i = 0; i < top; i++) {
BSSWAP(h->linp[i]);
p = (char *)GETBLEAF(h, i);
BLPSWAP(p);
p += sizeof(size_t);
BLPSWAP(p);
p += sizeof(size_t);
flags = *(u_char *)p;
if (flags & (P_BIGKEY | P_BIGDATA)) {
p += sizeof(u_char);
if (flags & P_BIGKEY) {
BLPSWAP(p);
p += sizeof(pgno_t);
BLPSWAP(p);
}
if (flags & P_BIGDATA) {
p += sizeof(size_t);
BLPSWAP(p);
p += sizeof(pgno_t);
BLPSWAP(p);
}
}
}
}
void
__bt_pgout(void *t, pgno_t pg, void *pp)
{
PAGE *h;
int i, top;
u_char flags;
char *p;
if (!ISSET(((BTREE *)t), B_NEEDSWAP))
return;
if (pg == P_META) {
mswap(pp);
return;
}
h = pp;
top = NEXTINDEX(h);
if ((h->flags & P_TYPE) == P_BINTERNAL)
for (i = 0; i < top; i++) {
p = (char *)GETBINTERNAL(h, i);
BLPSWAP(p);
p += sizeof(size_t);
BLPSWAP(p);
p += sizeof(pgno_t);
if (*(u_char *)p & P_BIGKEY) {
p += sizeof(u_char);
BLPSWAP(p);
p += sizeof(pgno_t);
BLPSWAP(p);
}
BSSWAP(h->linp[i]);
}
else if ((h->flags & P_TYPE) == P_BLEAF)
for (i = 0; i < top; i++) {
p = (char *)GETBLEAF(h, i);
BLPSWAP(p);
p += sizeof(size_t);
BLPSWAP(p);
p += sizeof(size_t);
flags = *(u_char *)p;
if (flags & (P_BIGKEY | P_BIGDATA)) {
p += sizeof(u_char);
if (flags & P_BIGKEY) {
BLPSWAP(p);
p += sizeof(pgno_t);
BLPSWAP(p);
}
if (flags & P_BIGDATA) {
p += sizeof(size_t);
BLPSWAP(p);
p += sizeof(pgno_t);
BLPSWAP(p);
}
}
BSSWAP(h->linp[i]);
}
BLSWAP(h->pgno);
BLSWAP(h->prevpg);
BLSWAP(h->nextpg);
BLSWAP(h->flags);
BSSWAP(h->lower);
BSSWAP(h->upper);
}
/*
* MSWAP -- Actually swap the bytes on the meta page.
*
* Parameters:
* p: page to convert
*/
static void
mswap(PAGE *pg)
{
char *p;
p = (char *)pg;
BLPSWAP(p); /* m_magic */
p += sizeof(u_long);
BLPSWAP(p); /* m_version */
p += sizeof(u_long);
BLPSWAP(p); /* m_psize */
p += sizeof(u_long);
BLPSWAP(p); /* m_free */
p += sizeof(u_long);
BLPSWAP(p); /* m_nrecs */
p += sizeof(u_long);
BLPSWAP(p); /* m_flags */
p += sizeof(u_long);
}

View file

@ -0,0 +1,355 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: bt_debug.c /main/4 1996/10/04 09:54:32 drk $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_debug.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
#include "btree.h"
#ifdef DEBUG
/*
* BT_DUMP -- Dump the tree
*
* Parameters:
* dbp: pointer to the DB
*/
void
__bt_dump(dbp)
DB *dbp;
{
BTREE *t;
PAGE *h;
pgno_t i;
char *sep;
t = dbp->internal;
(void)fprintf(stderr, "%s: pgsz %ld",
ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize);
if (ISSET(t, R_RECNO))
(void)fprintf(stderr, " keys %lu", t->bt_nrecs);
#undef X
#define X(flag, name) \
if (ISSET(t, flag)) { \
(void)fprintf(stderr, "%s%s", sep, name); \
sep = ", "; \
}
if (t->bt_flags) {
sep = " flags (";
X(B_DELCRSR, "DELCRSR");
X(R_FIXLEN, "FIXLEN");
X(B_INMEM, "INMEM");
X(B_NODUPS, "NODUPS");
X(B_RDONLY, "RDONLY");
X(R_RECNO, "RECNO");
X(B_SEQINIT, "SEQINIT");
X(B_METADIRTY,"METADIRTY");
(void)fprintf(stderr, ")\n");
}
#undef X
for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
__bt_dpage(h);
(void)mpool_put(t->bt_mp, h, 0);
}
}
/*
* BT_DMPAGE -- Dump the meta page
*
* Parameters:
* h: pointer to the PAGE
*/
void
__bt_dmpage(h)
PAGE *h;
{
BTMETA *m;
char *sep;
m = (BTMETA *)h;
(void)fprintf(stderr, "magic %lx\n", m->m_magic);
(void)fprintf(stderr, "version %lu\n", m->m_version);
(void)fprintf(stderr, "psize %lu\n", m->m_psize);
(void)fprintf(stderr, "free %lu\n", m->m_free);
(void)fprintf(stderr, "nrecs %lu\n", m->m_nrecs);
(void)fprintf(stderr, "flags %lu", m->m_flags);
#undef X
#define X(flag, name) \
if (m->m_flags & flag) { \
(void)fprintf(stderr, "%s%s", sep, name); \
sep = ", "; \
}
if (m->m_flags) {
sep = " (";
X(B_NODUPS, "NODUPS");
X(R_RECNO, "RECNO");
(void)fprintf(stderr, ")");
}
}
/*
* BT_DNPAGE -- Dump the page
*
* Parameters:
* n: page number to dump.
*/
void
__bt_dnpage(dbp, pgno)
DB *dbp;
pgno_t pgno;
{
BTREE *t;
PAGE *h;
t = dbp->internal;
if ((h = mpool_get(t->bt_mp, pgno, 0)) != NULL) {
__bt_dpage(h);
(void)mpool_put(t->bt_mp, h, 0);
}
}
/*
* BT_DPAGE -- Dump the page
*
* Parameters:
* h: pointer to the PAGE
*/
void
__bt_dpage(h)
PAGE *h;
{
BINTERNAL *bi;
BLEAF *bl;
RINTERNAL *ri;
RLEAF *rl;
indx_t cur, top;
char *sep;
(void)fprintf(stderr, " page %ld: (", h->pgno);
#undef X
#define X(flag, name) \
if (h->flags & flag) { \
(void)fprintf(stderr, "%s%s", sep, name); \
sep = ", "; \
}
sep = "";
X(P_BINTERNAL, "BINTERNAL") /* types */
X(P_BLEAF, "BLEAF")
X(P_RINTERNAL, "RINTERNAL") /* types */
X(P_RLEAF, "RLEAF")
X(P_OVERFLOW, "OVERFLOW")
X(P_PRESERVE, "PRESERVE");
(void)fprintf(stderr, ")\n");
#undef X
(void)fprintf(stderr, "\tprev %2ld next %2ld", h->prevpg, h->nextpg);
if (h->flags & P_OVERFLOW)
return;
top = NEXTINDEX(h);
(void)fprintf(stderr, " lower %3d upper %3d nextind %d\n",
h->lower, h->upper, top);
for (cur = 0; cur < top; cur++) {
(void)fprintf(stderr, "\t[%03d] %4d ", cur, h->linp[cur]);
switch(h->flags & P_TYPE) {
case P_BINTERNAL:
bi = GETBINTERNAL(h, cur);
(void)fprintf(stderr,
"size %03ld pgno %03ld", (long)bi->ksize, bi->pgno);
if (bi->flags & P_BIGKEY)
(void)fprintf(stderr, " (indirect)");
else if (bi->ksize)
(void)fprintf(stderr,
" {%.*s}", (int)bi->ksize, bi->bytes);
break;
case P_RINTERNAL:
ri = GETRINTERNAL(h, cur);
(void)fprintf(stderr, "entries %03ld pgno %03ld",
ri->nrecs, ri->pgno);
break;
case P_BLEAF:
bl = GETBLEAF(h, cur);
if (bl->flags & P_BIGKEY)
(void)fprintf(stderr,
"big key page %lu size %lu/",
*(pgno_t *)bl->bytes,
(long)*(size_t *)(bl->bytes + sizeof(pgno_t)));
else if (bl->ksize)
(void)fprintf(stderr, "%s/", bl->bytes);
if (bl->flags & P_BIGDATA)
(void)fprintf(stderr,
"big data page %lu size %lu",
*(pgno_t *)(bl->bytes + bl->ksize),
(long)*(size_t *)(bl->bytes + bl->ksize +
sizeof(pgno_t)));
else if (bl->dsize)
(void)fprintf(stderr, "%.*s",
(int)bl->dsize, bl->bytes + bl->ksize);
break;
case P_RLEAF:
rl = GETRLEAF(h, cur);
if (rl->flags & P_BIGDATA)
(void)fprintf(stderr,
"big data page %lu size %lu",
*(pgno_t *)rl->bytes,
(long)*(size_t *)(rl->bytes + sizeof(pgno_t)));
else if (rl->dsize)
(void)fprintf(stderr,
"%.*s", (int)rl->dsize, rl->bytes);
break;
}
(void)fprintf(stderr, "\n");
}
}
#endif
#ifdef STATISTICS
/*
* BT_STAT -- Gather/print the tree statistics
*
* Parameters:
* dbp: pointer to the DB
*/
void
__bt_stat(dbp)
DB *dbp;
{
extern u_long bt_cache_hit, bt_cache_miss;
extern u_long bt_rootsplit, bt_split, bt_sortsplit;
extern u_long bt_pfxsaved;
BTREE *t;
PAGE *h;
pgno_t i, pcont, pinternal, pleaf;
u_long ifree, lfree, nkeys;
int levels;
t = dbp->internal;
pcont = pinternal = pleaf = 0;
nkeys = ifree = lfree = 0;
for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
switch(h->flags & P_TYPE) {
case P_BINTERNAL:
case P_RINTERNAL:
++pinternal;
ifree += h->upper - h->lower;
break;
case P_BLEAF:
case P_RLEAF:
++pleaf;
lfree += h->upper - h->lower;
nkeys += NEXTINDEX(h);
break;
case P_OVERFLOW:
++pcont;
break;
}
(void)mpool_put(t->bt_mp, h, 0);
}
/* Count the levels of the tree. */
for (i = P_ROOT, levels = 0 ;; ++levels) {
h = mpool_get(t->bt_mp, i, 0);
if (h->flags & (P_BLEAF|P_RLEAF)) {
if (levels == 0)
levels = 1;
(void)mpool_put(t->bt_mp, h, 0);
break;
}
i = ISSET(t, R_RECNO) ?
GETRINTERNAL(h, 0)->pgno :
GETBINTERNAL(h, 0)->pgno;
(void)mpool_put(t->bt_mp, h, 0);
}
(void)fprintf(stderr, "%d level%s with %ld keys",
levels, levels == 1 ? "" : "s", nkeys);
if (ISSET(t, R_RECNO))
(void)fprintf(stderr, " (%ld header count)", t->bt_nrecs);
(void)fprintf(stderr,
"\n%lu pages (leaf %ld, internal %ld, overflow %ld)\n",
pinternal + pleaf + pcont, pleaf, pinternal, pcont);
(void)fprintf(stderr, "%ld cache hits, %ld cache misses\n",
bt_cache_hit, bt_cache_miss);
(void)fprintf(stderr, "%ld splits (%ld root splits, %ld sort splits)\n",
bt_split, bt_rootsplit, bt_sortsplit);
pleaf *= t->bt_psize - BTDATAOFF;
if (pleaf)
(void)fprintf(stderr,
"%.0f%% leaf fill (%ld bytes used, %ld bytes free)\n",
((double)(pleaf - lfree) / pleaf) * 100,
pleaf - lfree, lfree);
pinternal *= t->bt_psize - BTDATAOFF;
if (pinternal)
(void)fprintf(stderr,
"%.0f%% internal fill (%ld bytes used, %ld bytes free\n",
((double)(pinternal - ifree) / pinternal) * 100,
pinternal - ifree, ifree);
if (bt_pfxsaved)
(void)fprintf(stderr, "prefix checking removed %lu bytes.\n",
bt_pfxsaved);
}
#endif

View file

@ -0,0 +1,340 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: bt_delete.c /main/3 1996/06/11 17:12:29 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_delete.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <db.h>
#include "btree.h"
static int bt_bdelete __P((BTREE *, const DBT *));
/*
* __BT_DELETE -- Delete the item(s) referenced by a key.
*
* Parameters:
* dbp: pointer to access method
* key: key to delete
* flags: R_CURSOR if deleting what the cursor references
*
* Returns:
* RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
*/
int
__bt_delete(const DB *dbp, const DBT *key, u_int flags)
{
BTREE *t;
int status;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
if (ISSET(t, B_RDONLY)) {
errno = EPERM;
return (RET_ERROR);
}
switch(flags) {
case 0:
status = bt_bdelete(t, key);
break;
case R_CURSOR:
/*
* If flags is R_CURSOR, delete the cursor; must already have
* started a scan and not have already deleted the record. For
* the delete cursor bit to have been set requires that the
* scan be initialized, so no reason to check.
*/
if (!ISSET(t, B_SEQINIT))
goto einval;
status = ISSET(t, B_DELCRSR) ?
RET_SPECIAL : __bt_crsrdel(t, &t->bt_bcursor);
break;
default:
einval: errno = EINVAL;
return (RET_ERROR);
}
if (status == RET_SUCCESS)
SET(t, B_MODIFIED);
return (status);
}
/*
* BT_BDELETE -- Delete all key/data pairs matching the specified key.
*
* Parameters:
* tree: tree
* key: key to delete
*
* Returns:
* RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
*/
static int
bt_bdelete(BTREE *t, const DBT *key)
{
EPG *e, save;
PAGE *h;
pgno_t cpgno, pg;
indx_t cindex;
int deleted, dirty1, dirty2, exact;
/* Find any matching record; __bt_search pins the page. */
if ((e = __bt_search(t, key, &exact)) == NULL)
return (RET_ERROR);
if (!exact) {
mpool_put(t->bt_mp, e->page, 0);
return (RET_SPECIAL);
}
/*
* Delete forward, then delete backward, from the found key. The
* ordering is so that the deletions don't mess up the page refs.
* The first loop deletes the key from the original page, the second
* unpins the original page. In the first loop, dirty1 is set if
* the original page is modified, and dirty2 is set if any subsequent
* pages are modified. In the second loop, dirty1 starts off set if
* the original page has been modified, and is set if any subsequent
* pages are modified.
*
* If find the key referenced by the cursor, don't delete it, just
* flag it for future deletion. The cursor page number is P_INVALID
* unless the sequential scan is initialized, so no reason to check.
* A special case is when the already deleted cursor record was the
* only record found. If so, then the delete opertion fails as no
* records were deleted.
*
* Cycle in place in the current page until the current record doesn't
* match the key or the page is empty. If the latter, walk forward,
* skipping empty pages and repeating until a record doesn't match
* the key or the end of the tree is reached.
*/
cpgno = t->bt_bcursor.pgno;
cindex = t->bt_bcursor.index;
save = *e;
dirty1 = 0;
for (h = e->page, deleted = 0;;) {
dirty2 = 0;
do {
if (h->pgno == cpgno && e->index == cindex) {
if (!ISSET(t, B_DELCRSR)) {
SET(t, B_DELCRSR);
deleted = 1;
}
++e->index;
} else {
if (__bt_dleaf(t, h, e->index)) {
if (h->pgno != save.page->pgno)
mpool_put(t->bt_mp, h, dirty2);
mpool_put(t->bt_mp, save.page, dirty1);
return (RET_ERROR);
}
if (h->pgno == save.page->pgno)
dirty1 = MPOOL_DIRTY;
else
dirty2 = MPOOL_DIRTY;
deleted = 1;
}
} while (e->index < NEXTINDEX(h) && __bt_cmp(t, key, e) == 0);
/*
* Quit if didn't find a match, no next page, or first key on
* the next page doesn't match. Don't unpin the original page
* unless an error occurs.
*/
if (e->index < NEXTINDEX(h))
break;
for (;;) {
if ((pg = h->nextpg) == P_INVALID)
goto done1;
if (h->pgno != save.page->pgno)
mpool_put(t->bt_mp, h, dirty2);
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) {
mpool_put(t->bt_mp, save.page, dirty1);
return (RET_ERROR);
}
if (NEXTINDEX(h) != 0) {
e->page = h;
e->index = 0;
break;
}
}
if (__bt_cmp(t, key, e) != 0)
break;
}
/*
* Reach here with the original page and the last page referenced
* pinned (they may be the same). Release it if not the original.
*/
done1: if (h->pgno != save.page->pgno)
mpool_put(t->bt_mp, h, dirty2);
/*
* Walk backwards from the record previous to the record returned by
* __bt_search, skipping empty pages, until a record doesn't match
* the key or reach the beginning of the tree.
*/
*e = save;
for (;;) {
if (e->index)
--e->index;
for (h = e->page; e->index; --e->index) {
if (__bt_cmp(t, key, e) != 0)
goto done2;
if (h->pgno == cpgno && e->index == cindex) {
if (!ISSET(t, B_DELCRSR)) {
SET(t, B_DELCRSR);
deleted = 1;
}
} else {
if (__bt_dleaf(t, h, e->index) == RET_ERROR) {
mpool_put(t->bt_mp, h, dirty1);
return (RET_ERROR);
}
if (h->pgno == save.page->pgno)
dirty1 = MPOOL_DIRTY;
deleted = 1;
}
}
if ((pg = h->prevpg) == P_INVALID)
goto done2;
mpool_put(t->bt_mp, h, dirty1);
dirty1 = 0;
if ((e->page = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
e->index = NEXTINDEX(e->page);
}
/*
* Reach here with the last page that was looked at pinned. Release
* it.
*/
done2: mpool_put(t->bt_mp, h, dirty1);
return (deleted ? RET_SUCCESS : RET_SPECIAL);
}
/*
* __BT_DLEAF -- Delete a single record from a leaf page.
*
* Parameters:
* t: tree
* index: index on current page to delete
*
* Returns:
* RET_SUCCESS, RET_ERROR.
*/
int
__bt_dleaf(BTREE *t, PAGE *h, int index)
{
BLEAF *bl;
indx_t *ip, offset;
size_t nbytes;
int cnt;
char *from;
void *to;
/*
* Delete a record from a btree leaf page. Internal records are never
* deleted from internal pages, regardless of the records that caused
* them to be added being deleted. Pages made empty by deletion are
* not reclaimed. They are, however, made available for reuse.
*
* Pack the remaining entries at the end of the page, shift the indices
* down, overwriting the deleted record and its index. If the record
* uses overflow pages, make them available for reuse.
*/
to = bl = GETBLEAF(h, index);
if (bl->flags & P_BIGKEY && __ovfl_delete(t, bl->bytes) == RET_ERROR)
return (RET_ERROR);
if (bl->flags & P_BIGDATA &&
__ovfl_delete(t, bl->bytes + bl->ksize) == RET_ERROR)
return (RET_ERROR);
nbytes = NBLEAF(bl);
/*
* Compress the key/data pairs. Compress and adjust the [BR]LEAF
* offsets. Reset the headers.
*/
from = (char *)h + h->upper;
memmove(from + nbytes, from, (char *)to - from);
h->upper += nbytes;
offset = h->linp[index];
for (cnt = index, ip = &h->linp[0]; cnt--; ++ip)
if (ip[0] < offset)
ip[0] += nbytes;
for (cnt = NEXTINDEX(h) - index; --cnt; ++ip)
ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1];
h->lower -= sizeof(indx_t);
return (RET_SUCCESS);
}

View file

@ -0,0 +1,254 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: bt_get.c /main/3 1996/06/11 17:12:34 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_get.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <db.h>
#include "btree.h"
/*
* __BT_GET -- Get a record from the btree.
*
* Parameters:
* dbp: pointer to access method
* key: key to find
* data: data to return
* flag: currently unused
*
* Returns:
* RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
*/
int
__bt_get(const DB *dbp, const DBT *key, DBT *data, u_int flags)
{
BTREE *t;
EPG *e;
int exact, status;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
/* Get currently doesn't take any flags. */
if (flags) {
errno = EINVAL;
return (RET_ERROR);
}
if ((e = __bt_search(t, key, &exact)) == NULL)
return (RET_ERROR);
if (!exact) {
mpool_put(t->bt_mp, e->page, 0);
return (RET_SPECIAL);
}
/*
* A special case is if we found the record but it's flagged for
* deletion. In this case, we want to find another record with the
* same key, if it exists. Rather than look around the tree we call
* __bt_first and have it redo the search, as __bt_first will not
* return keys marked for deletion. Slow, but should never happen.
*/
if (ISSET(t, B_DELCRSR) && e->page->pgno == t->bt_bcursor.pgno &&
e->index == t->bt_bcursor.index) {
mpool_put(t->bt_mp, e->page, 0);
if ((e = __bt_first(t, key, &exact)) == NULL)
return (RET_ERROR);
if (!exact)
return (RET_SPECIAL);
}
status = __bt_ret(t, e, NULL, data);
/*
* If the user is doing concurrent access, we copied the
* key/data, toss the page.
*/
if (ISSET(t, B_DB_LOCK))
mpool_put(t->bt_mp, e->page, 0);
else
t->bt_pinned = e->page;
return (status);
}
/*
* __BT_FIRST -- Find the first entry.
*
* Parameters:
* t: the tree
* key: the key
*
* Returns:
* The first entry in the tree greater than or equal to key.
*/
EPG *
__bt_first(BTREE *t, const DBT *key, int *exactp)
{
PAGE *h;
EPG *e;
EPG save;
pgno_t cpgno, pg;
indx_t cindex;
int found;
/*
* Find any matching record; __bt_search pins the page. Only exact
* matches are tricky, otherwise just return the location of the key
* if it were to be inserted into the tree.
*/
if ((e = __bt_search(t, key, exactp)) == NULL)
return (NULL);
if (!*exactp)
return (e);
if (ISSET(t, B_DELCRSR)) {
cpgno = t->bt_bcursor.pgno;
cindex = t->bt_bcursor.index;
} else {
cpgno = P_INVALID;
cindex = 0; /* GCC thinks it's uninitialized. */
}
/*
* Walk backwards, skipping empty pages, as long as the entry matches
* and there are keys left in the tree. Save a copy of each match in
* case we go too far. A special case is that we don't return a match
* on records that the cursor references that have already been flagged
* for deletion.
*/
save = *e;
h = e->page;
found = 0;
do {
if (cpgno != h->pgno || cindex != e->index) {
if (save.page->pgno != e->page->pgno) {
mpool_put(t->bt_mp, save.page, 0);
save = *e;
} else
save.index = e->index;
found = 1;
}
/*
* Make a special effort not to unpin the page the last (or
* original) match was on, but also make sure it's unpinned
* if an error occurs.
*/
while (e->index == 0) {
if (h->prevpg == P_INVALID)
goto done1;
if (h->pgno != save.page->pgno)
mpool_put(t->bt_mp, h, 0);
if ((h = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL) {
if (h->pgno == save.page->pgno)
mpool_put(t->bt_mp, save.page, 0);
return (NULL);
}
e->page = h;
e->index = NEXTINDEX(h);
}
--e->index;
} while (__bt_cmp(t, key, e) == 0);
/*
* Reach here with the last page that was looked at pinned, which may
* or may not be the same as the last (or original) match page. If
* it's not useful, release it.
*/
done1: if (h->pgno != save.page->pgno)
mpool_put(t->bt_mp, h, 0);
/*
* If still haven't found a record, the only possibility left is the
* next one. Move forward one slot, skipping empty pages and check.
*/
if (!found) {
h = save.page;
if (++save.index == NEXTINDEX(h)) {
do {
pg = h->nextpg;
mpool_put(t->bt_mp, h, 0);
if (pg == P_INVALID) {
*exactp = 0;
return (e);
}
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (NULL);
} while ((save.index = NEXTINDEX(h)) == 0);
save.page = h;
}
if (__bt_cmp(t, key, &save) != 0) {
*exactp = 0;
return (e);
}
}
*e = save;
*exactp = 1;
return (e);
}

View file

@ -0,0 +1,461 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: bt_open.c /main/3 1996/06/11 17:12:40 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_open.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
/*
* Implementation of btree access method for 4.4BSD.
*
* The design here was originally based on that of the btree access method
* used in the Postgres database system at UC Berkeley. This implementation
* is wholly independent of the Postgres code.
*/
#include <sys/param.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define __DBINTERFACE_PRIVATE
#include <db.h>
#include "btree.h"
static int byteorder __P((void));
static int nroot __P((BTREE *));
static int tmp __P((void));
/*
* __BT_OPEN -- Open a btree.
*
* Creates and fills a DB struct, and calls the routine that actually
* opens the btree.
*
* Parameters:
* fname: filename (NULL for in-memory trees)
* flags: open flag bits
* mode: open permission bits
* b: BTREEINFO pointer
*
* Returns:
* NULL on failure, pointer to DB on success.
*
*/
DB *
__bt_open(const char *fname, int flags, int mode, const BTREEINFO *openinfo, int dflags)
{
BTMETA m;
BTREE *t;
BTREEINFO b;
DB *dbp;
pgno_t ncache;
struct stat sb;
int machine_lorder, nr;
t = NULL;
/*
* Intention is to make sure all of the user's selections are okay
* here and then use them without checking. Can't be complete, since
* we don't know the right page size, lorder or flags until the backing
* file is opened. Also, the file's page size can cause the cachesize
* to change.
*/
machine_lorder = byteorder();
if (openinfo) {
b = *openinfo;
/* Flags: R_DUP. */
if (b.flags & ~(R_DUP))
goto einval;
/*
* Page size must be indx_t aligned and >= MINPSIZE. Default
* page size is set farther on, based on the underlying file
* transfer size.
*/
if (b.psize &&
(b.psize < MINPSIZE || b.psize > MAX_PAGE_OFFSET + 1 ||
b.psize & (sizeof(indx_t) - 1)))
goto einval;
/* Minimum number of keys per page; absolute minimum is 2. */
if (b.minkeypage) {
if (b.minkeypage < 2)
goto einval;
} else
b.minkeypage = DEFMINKEYPAGE;
/* If no comparison, use default comparison and prefix. */
if (b.compare == NULL) {
b.compare = __bt_defcmp;
if (b.prefix == NULL)
b.prefix = __bt_defpfx;
}
if (b.lorder == 0)
b.lorder = machine_lorder;
} else {
b.compare = __bt_defcmp;
b.cachesize = 0;
b.flags = 0;
b.lorder = machine_lorder;
b.minkeypage = DEFMINKEYPAGE;
b.prefix = __bt_defpfx;
b.psize = 0;
}
/* Check for the ubiquitous PDP-11. */
if (b.lorder != BIG_ENDIAN && b.lorder != LITTLE_ENDIAN)
goto einval;
/* Allocate and initialize DB and BTREE structures. */
if ((t = malloc(sizeof(BTREE))) == NULL)
goto err;
t->bt_fd = -1; /* Don't close unopened fd on error. */
if ((t->bt_dbp = dbp = malloc(sizeof(DB))) == NULL)
goto err;
t->bt_bcursor.pgno = P_INVALID;
t->bt_bcursor.index = 0;
t->bt_stack = NULL;
t->bt_pinned = NULL;
t->bt_sp = t->bt_maxstack = 0;
t->bt_kbuf = t->bt_dbuf = NULL;
t->bt_kbufsz = t->bt_dbufsz = 0;
t->bt_lorder = b.lorder;
t->bt_order = NOT;
t->bt_cmp = b.compare;
t->bt_pfx = b.prefix;
t->bt_flags = 0;
if (t->bt_lorder != machine_lorder)
SET(t, B_NEEDSWAP);
dbp->type = DB_BTREE;
dbp->internal = t;
dbp->close = __bt_close;
dbp->del = __bt_delete;
dbp->fd = __bt_fd;
dbp->get = __bt_get;
dbp->put = __bt_put;
dbp->seq = __bt_seq;
dbp->sync = __bt_sync;
/*
* If no file name was supplied, this is an in-memory btree and we
* open a backing temporary file. Otherwise, it's a disk-based tree.
*/
if (fname) {
switch(flags & O_ACCMODE) {
case O_RDONLY:
SET(t, B_RDONLY);
break;
case O_RDWR:
break;
case O_WRONLY:
default:
goto einval;
}
if ((t->bt_fd = open(fname, flags, mode)) < 0)
goto err;
} else {
if ((flags & O_ACCMODE) != O_RDWR)
goto einval;
if ((t->bt_fd = tmp()) == -1)
goto err;
SET(t, B_INMEM);
}
if (fcntl(t->bt_fd, F_SETFD, 1) == -1)
goto err;
if (fstat(t->bt_fd, &sb))
goto err;
if (sb.st_size) {
nr = read(t->bt_fd, &m, sizeof(BTMETA));
if (nr < 0)
goto err;
if (nr != sizeof(BTMETA))
goto eftype;
/*
* Read in the meta-data. This can change the notion of what
* the lorder, page size and flags are, and, when the page size
* changes, the cachesize value can change too. If the user
* specified the wrong byte order for an existing database, we
* don't bother to return an error, we just clear the NEEDSWAP
* bit.
*/
if (m.m_magic == BTREEMAGIC)
CLR(t, B_NEEDSWAP);
else {
SET(t, B_NEEDSWAP);
BLSWAP(m.m_magic);
BLSWAP(m.m_version);
BLSWAP(m.m_psize);
BLSWAP(m.m_free);
BLSWAP(m.m_nrecs);
BLSWAP(m.m_flags);
}
if (m.m_magic != BTREEMAGIC || m.m_version != BTREEVERSION)
goto eftype;
if (m.m_psize < MINPSIZE || m.m_psize > MAX_PAGE_OFFSET + 1 ||
m.m_psize & (sizeof(indx_t) - 1))
goto eftype;
if (m.m_flags & ~SAVEMETA)
goto eftype;
b.psize = m.m_psize;
t->bt_flags |= m.m_flags;
t->bt_free = m.m_free;
t->bt_nrecs = m.m_nrecs;
} else {
/*
* Set the page size to the best value for I/O to this file.
* Don't overflow the page offset type.
*/
if (b.psize == 0) {
b.psize = sb.st_blksize;
if (b.psize < MINPSIZE)
b.psize = MINPSIZE;
if (b.psize > MAX_PAGE_OFFSET + 1)
b.psize = MAX_PAGE_OFFSET + 1;
}
/* Set flag if duplicates permitted. */
if (!(b.flags & R_DUP))
SET(t, B_NODUPS);
t->bt_free = P_INVALID;
t->bt_nrecs = 0;
SET(t, B_METADIRTY);
}
t->bt_psize = b.psize;
/* Set the cache size; must be a multiple of the page size. */
if (b.cachesize && b.cachesize & (b.psize - 1))
b.cachesize += (~b.cachesize & (b.psize - 1)) + 1;
if (b.cachesize < b.psize * MINCACHE)
b.cachesize = b.psize * MINCACHE;
/* Calculate number of pages to cache. */
ncache = (b.cachesize + t->bt_psize - 1) / t->bt_psize;
/*
* The btree data structure requires that at least two keys can fit on
* a page, but other than that there's no fixed requirement. The user
* specified a minimum number per page, and we translated that into the
* number of bytes a key/data pair can use before being placed on an
* overflow page. This calculation includes the page header, the size
* of the index referencing the leaf item and the size of the leaf item
* structure. Also, don't let the user specify a minkeypage such that
* a key/data pair won't fit even if both key and data are on overflow
* pages.
*/
t->bt_ovflsize = (t->bt_psize - BTDATAOFF) / b.minkeypage -
(sizeof(indx_t) + NBLEAFDBT(0, 0));
if (t->bt_ovflsize < NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t))
t->bt_ovflsize =
NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t);
/* Initialize the buffer pool. */
if ((t->bt_mp =
mpool_open(NULL, t->bt_fd, t->bt_psize, ncache)) == NULL)
goto err;
if (!ISSET(t, B_INMEM))
mpool_filter(t->bt_mp, __bt_pgin, __bt_pgout, t);
/* Create a root page if new tree. */
if (nroot(t) == RET_ERROR)
goto err;
/* Global flags. */
if (dflags & DB_LOCK)
SET(t, B_DB_LOCK);
if (dflags & DB_SHMEM)
SET(t, B_DB_SHMEM);
if (dflags & DB_TXN)
SET(t, B_DB_TXN);
return (dbp);
einval: errno = EINVAL;
goto err;
eftype: errno = EFTYPE;
goto err;
err: if (t) {
if (t->bt_dbp)
free(t->bt_dbp);
if (t->bt_fd != -1)
(void)close(t->bt_fd);
free(t);
}
return (NULL);
}
/*
* NROOT -- Create the root of a new tree.
*
* Parameters:
* t: tree
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
static int
nroot(BTREE *t)
{
PAGE *meta, *root;
pgno_t npg;
if ((meta = mpool_get(t->bt_mp, 0, 0)) != NULL) {
mpool_put(t->bt_mp, meta, 0);
return (RET_SUCCESS);
}
if (errno != EINVAL)
return (RET_ERROR);
if ((meta = mpool_new(t->bt_mp, &npg)) == NULL)
return (RET_ERROR);
if ((root = mpool_new(t->bt_mp, &npg)) == NULL)
return (RET_ERROR);
if (npg != P_ROOT)
return (RET_ERROR);
root->pgno = npg;
root->prevpg = root->nextpg = P_INVALID;
root->lower = BTDATAOFF;
root->upper = t->bt_psize;
root->flags = P_BLEAF;
memset(meta, 0, t->bt_psize);
mpool_put(t->bt_mp, meta, MPOOL_DIRTY);
mpool_put(t->bt_mp, root, MPOOL_DIRTY);
return (RET_SUCCESS);
}
static int
tmp(void)
{
sigset_t set, oset;
int fd;
char *envtmp;
char path[MAXPATHLEN];
envtmp = getenv("TMPDIR");
(void)snprintf(path,
sizeof(path), "%s/bt.XXXXXX", envtmp ? envtmp : "/tmp");
(void)sigfillset(&set);
(void)sigprocmask(SIG_BLOCK, &set, &oset);
if ((fd = mkstemp(path)) != -1)
(void)unlink(path);
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
return(fd);
}
static int
byteorder(void)
{
u_long x; /* XXX: 32-bit assumption. */
u_char *p;
x = 0x01020304;
p = (u_char *)&x;
switch (*p) {
case 1:
return (BIG_ENDIAN);
case 4:
return (LITTLE_ENDIAN);
default:
return (0);
}
}
int
__bt_fd(const DB *dbp)
{
BTREE *t;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
/* In-memory database can't have a file descriptor. */
if (ISSET(t, B_INMEM)) {
errno = ENOENT;
return (-1);
}
return (t->bt_fd);
}

View file

@ -0,0 +1,237 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: bt_overflow.c /main/3 1996/06/11 17:12:45 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_overflow.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
#include "btree.h"
/*
* Big key/data code.
*
* Big key and data entries are stored on linked lists of pages. The initial
* reference is byte string stored with the key or data and is the page number
* and size. The actual record is stored in a chain of pages linked by the
* nextpg field of the PAGE header.
*
* The first page of the chain has a special property. If the record is used
* by an internal page, it cannot be deleted and the P_PRESERVE bit will be set
* in the header.
*
* XXX
* A single DBT is written to each chain, so a lot of space on the last page
* is wasted. This is a fairly major bug for some data sets.
*/
/*
* __OVFL_GET -- Get an overflow key/data item.
*
* Parameters:
* t: tree
* p: pointer to { pgno_t, size_t }
* buf: storage address
* bufsz: storage size
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__ovfl_get(BTREE *t, void *p, size_t *ssz, char **buf, size_t *bufsz)
{
PAGE *h;
pgno_t pg;
size_t nb, plen, sz;
memmove(&pg, p, sizeof(pgno_t));
memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(size_t));
*ssz = sz;
#ifdef DEBUG
if (pg == P_INVALID || sz == 0)
abort();
#endif
/* Make the buffer bigger as necessary. */
if (*bufsz < sz) {
if ((*buf = __fix_realloc(*buf, sz)) == NULL)
return (RET_ERROR);
*bufsz = sz;
}
/*
* Step through the linked list of pages, copying the data on each one
* into the buffer. Never copy more than the data's length.
*/
plen = t->bt_psize - BTDATAOFF;
for (p = *buf;; p = (char *)p + nb, pg = h->nextpg) {
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
nb = MIN(sz, plen);
memmove(p, (char *)h + BTDATAOFF, nb);
mpool_put(t->bt_mp, h, 0);
if ((sz -= nb) == 0)
break;
}
return (RET_SUCCESS);
}
/*
* __OVFL_PUT -- Store an overflow key/data item.
*
* Parameters:
* t: tree
* data: DBT to store
* pgno: storage page number
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__ovfl_put(BTREE *t, const DBT *dbt, pgno_t *pg)
{
PAGE *h, *last;
void *p;
pgno_t npg;
size_t nb, plen, sz;
/*
* Allocate pages and copy the key/data record into them. Store the
* number of the first page in the chain.
*/
plen = t->bt_psize - BTDATAOFF;
for (last = NULL, p = dbt->data, sz = dbt->size;;
p = (char *)p + plen, last = h) {
if ((h = __bt_new(t, &npg)) == NULL)
return (RET_ERROR);
h->pgno = npg;
h->nextpg = h->prevpg = P_INVALID;
h->flags = P_OVERFLOW;
h->lower = h->upper = 0;
nb = MIN(sz, plen);
memmove((char *)h + BTDATAOFF, p, nb);
if (last) {
last->nextpg = h->pgno;
mpool_put(t->bt_mp, last, MPOOL_DIRTY);
} else
*pg = h->pgno;
if ((sz -= nb) == 0) {
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
break;
}
}
return (RET_SUCCESS);
}
/*
* __OVFL_DELETE -- Delete an overflow chain.
*
* Parameters:
* t: tree
* p: pointer to { pgno_t, size_t }
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__ovfl_delete(BTREE *t, void *p)
{
PAGE *h;
pgno_t pg;
size_t plen, sz;
memmove(&pg, p, sizeof(pgno_t));
memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(size_t));
#ifdef DEBUG
if (pg == P_INVALID || sz == 0)
abort();
#endif
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
/* Don't delete chains used by internal pages. */
if (h->flags & P_PRESERVE) {
mpool_put(t->bt_mp, h, 0);
return (RET_SUCCESS);
}
/* Step through the chain, calling the free routine for each page. */
for (plen = t->bt_psize - BTDATAOFF;; sz -= plen) {
pg = h->nextpg;
__bt_free(t, h);
if (sz <= plen)
break;
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
}
return (RET_SUCCESS);
}

View file

@ -0,0 +1,113 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: bt_page.c /main/3 1996/06/11 17:12:50 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_page.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#define __DBINTERFACE_PRIVATE
#include <stdio.h>
#include <db.h>
#include "btree.h"
/*
* __BT_FREE -- Put a page on the freelist.
*
* Parameters:
* t: tree
* h: page to free
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__bt_free(BTREE *t, PAGE *h)
{
/* Insert the page at the start of the free list. */
h->prevpg = P_INVALID;
h->nextpg = t->bt_free;
t->bt_free = h->pgno;
/* Make sure the page gets written back. */
return (mpool_put(t->bt_mp, h, MPOOL_DIRTY));
}
/*
* __BT_NEW -- Get a new page, preferably from the freelist.
*
* Parameters:
* t: tree
* npg: storage for page number.
*
* Returns:
* Pointer to a page, NULL on error.
*/
PAGE *
__bt_new(BTREE *t, pgno_t *npg)
{
PAGE *h;
if (t->bt_free != P_INVALID &&
(h = mpool_get(t->bt_mp, t->bt_free, 0)) != NULL) {
*npg = t->bt_free;
t->bt_free = h->nextpg;
return (h);
}
return (mpool_new(t->bt_mp, npg));
}

View file

@ -0,0 +1,336 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: bt_put.c /main/3 1996/06/11 17:12:56 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_put.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
#include "btree.h"
static EPG *bt_fast __P((BTREE *, const DBT *, const DBT *, int *));
/*
* __BT_PUT -- Add a btree item to the tree.
*
* Parameters:
* dbp: pointer to access method
* key: key
* data: data
* flag: R_NOOVERWRITE
*
* Returns:
* RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is already in the
* tree and R_NOOVERWRITE specified.
*/
int
__bt_put(const DB *dbp, DBT *key, const DBT *data, u_int flags)
{
BTREE *t;
DBT tkey, tdata;
EPG *e = NULL;
PAGE *h;
indx_t index, nxtindex;
pgno_t pg;
size_t nbytes;
int dflags, exact, status;
char *dest, db[NOVFLSIZE], kb[NOVFLSIZE];
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
switch (flags) {
case R_CURSOR:
if (!ISSET(t, B_SEQINIT))
goto einval;
if (ISSET(t, B_DELCRSR))
goto einval;
break;
case 0:
case R_NOOVERWRITE:
break;
default:
einval: errno = EINVAL;
return (RET_ERROR);
}
if (ISSET(t, B_RDONLY)) {
errno = EPERM;
return (RET_ERROR);
}
/*
* If the key/data won't fit on a page, store it on indirect pages.
* Only store the key on the overflow page if it's too big after the
* data is on an overflow page.
*
* XXX
* If the insert fails later on, these pages aren't recovered.
*/
dflags = 0;
if (key->size + data->size > t->bt_ovflsize) {
if (key->size > t->bt_ovflsize) {
storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR)
return (RET_ERROR);
tkey.data = kb;
tkey.size = NOVFLSIZE;
memmove(kb, &pg, sizeof(pgno_t));
memmove(kb + sizeof(pgno_t),
&key->size, sizeof(size_t));
dflags |= P_BIGKEY;
key = &tkey;
}
if (key->size + data->size > t->bt_ovflsize) {
if (__ovfl_put(t, data, &pg) == RET_ERROR)
return (RET_ERROR);
tdata.data = db;
tdata.size = NOVFLSIZE;
memmove(db, &pg, sizeof(pgno_t));
memmove(db + sizeof(pgno_t),
&data->size, sizeof(size_t));
dflags |= P_BIGDATA;
data = &tdata;
}
if (key->size + data->size > t->bt_ovflsize)
goto storekey;
}
/* Replace the cursor. */
if (flags == R_CURSOR) {
if ((h = mpool_get(t->bt_mp, t->bt_bcursor.pgno, 0)) == NULL)
return (RET_ERROR);
index = t->bt_bcursor.index;
goto delete;
}
/*
* Find the key to delete, or, the location at which to insert. Bt_fast
* and __bt_search pin the returned page.
*/
if (t->bt_order == NOT || (e = bt_fast(t, key, data, &exact)) == NULL)
if ((e = __bt_search(t, key, &exact)) == NULL)
return (RET_ERROR);
h = e->page;
index = e->index;
/*
* Add the specified key/data pair to the tree. If an identical key
* is already in the tree, and R_NOOVERWRITE is set, an error is
* returned. If R_NOOVERWRITE is not set, the key is either added (if
* duplicates are permitted) or an error is returned.
*
* Pages are split as required.
*/
switch (flags) {
case R_NOOVERWRITE:
if (!exact)
break;
/*
* One special case is if the cursor references the record and
* it's been flagged for deletion. Then, we delete the record,
* leaving the cursor there -- this means that the inserted
* record will not be seen in a cursor scan.
*/
if (ISSET(t, B_DELCRSR) && t->bt_bcursor.pgno == h->pgno &&
t->bt_bcursor.index == index) {
CLR(t, B_DELCRSR);
goto delete;
}
mpool_put(t->bt_mp, h, 0);
return (RET_SPECIAL);
default:
if (!exact || !ISSET(t, B_NODUPS))
break;
delete: if (__bt_dleaf(t, h, index) == RET_ERROR) {
mpool_put(t->bt_mp, h, 0);
return (RET_ERROR);
}
break;
}
/*
* If not enough room, or the user has put a ceiling on the number of
* keys permitted in the page, split the page. The split code will
* insert the key and data and unpin the current page. If inserting
* into the offset array, shift the pointers up.
*/
nbytes = NBLEAFDBT(key->size, data->size);
if (h->upper - h->lower < nbytes + sizeof(indx_t)) {
if ((status = __bt_split(t, h, key,
data, dflags, nbytes, index)) != RET_SUCCESS)
return (status);
goto success;
}
if (index < (nxtindex = NEXTINDEX(h)))
memmove(h->linp + index + 1, h->linp + index,
(nxtindex - index) * sizeof(indx_t));
h->lower += sizeof(indx_t);
h->linp[index] = h->upper -= nbytes;
dest = (char *)h + h->upper;
WR_BLEAF(dest, key, data, dflags);
if (t->bt_order == NOT) {
if (h->nextpg == P_INVALID) {
if (index == NEXTINDEX(h) - 1) {
t->bt_order = FORWARD;
t->bt_last.index = index;
t->bt_last.pgno = h->pgno;
}
} else if (h->prevpg == P_INVALID) {
if (index == 0) {
t->bt_order = BACK;
t->bt_last.index = 0;
t->bt_last.pgno = h->pgno;
}
}
}
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
success:
if (flags == R_SETCURSOR) {
t->bt_bcursor.pgno = e->page->pgno;
t->bt_bcursor.index = e->index;
}
SET(t, B_MODIFIED);
return (RET_SUCCESS);
}
#ifdef STATISTICS
u_long bt_cache_hit, bt_cache_miss;
#endif
/*
* BT_FAST -- Do a quick check for sorted data.
*
* Parameters:
* t: tree
* key: key to insert
*
* Returns:
* EPG for new record or NULL if not found.
*/
static EPG *
bt_fast(BTREE *t, const DBT *key, const DBT *data, int *exactp)
{
static EPG e;
PAGE *h;
size_t nbytes;
int cmp;
if ((h = mpool_get(t->bt_mp, t->bt_last.pgno, 0)) == NULL) {
t->bt_order = NOT;
return (NULL);
}
e.page = h;
e.index = t->bt_last.index;
/*
* If won't fit in this page or have too many keys in this page, have
* to search to get split stack.
*/
nbytes = NBLEAFDBT(key->size, data->size);
if (h->upper - h->lower < nbytes + sizeof(indx_t))
goto miss;
if (t->bt_order == FORWARD) {
if (e.page->nextpg != P_INVALID)
goto miss;
if (e.index != NEXTINDEX(h) - 1)
goto miss;
if ((cmp = __bt_cmp(t, key, &e)) < 0)
goto miss;
t->bt_last.index = cmp ? ++e.index : e.index;
} else {
if (e.page->prevpg != P_INVALID)
goto miss;
if (e.index != 0)
goto miss;
if ((cmp = __bt_cmp(t, key, &e)) > 0)
goto miss;
t->bt_last.index = 0;
}
*exactp = cmp == 0;
#ifdef STATISTICS
++bt_cache_hit;
#endif
return (&e);
miss:
#ifdef STATISTICS
++bt_cache_miss;
#endif
t->bt_order = NOT;
mpool_put(t->bt_mp, h, 0);
return (NULL);
}

View file

@ -0,0 +1,139 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: bt_search.c /main/3 1996/06/11 17:13:01 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_search.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <stdio.h>
#include <db.h>
#include "btree.h"
/*
* __BT_SEARCH -- Search a btree for a key.
*
* Parameters:
* t: tree to search
* key: key to find
* exactp: pointer to exact match flag
*
* Returns:
* EPG for matching record, if any, or the EPG for the location of the
* key, if it were inserted into the tree.
*
* Warnings:
* The EPG returned is in static memory, and will be overwritten by the
* next search of any kind in any tree.
*/
EPG *
__bt_search(BTREE *t, const DBT *key, int *exactp)
{
indx_t index;
int base, cmp, lim;
PAGE *h;
pgno_t pg;
static EPG e;
BT_CLR(t);
for (pg = P_ROOT;;) {
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (NULL);
/* Do a binary search on the current page. */
e.page = h;
for (base = 0, lim = NEXTINDEX(h); lim; lim >>= 1) {
e.index = index = base + (lim >> 1);
if ((cmp = __bt_cmp(t, key, &e)) == 0) {
if (h->flags & P_BLEAF) {
*exactp = 1;
return (&e);
}
goto next;
}
if (cmp > 0) {
base = index + 1;
--lim;
}
}
/* If it's a leaf page, we're done. */
if (h->flags & P_BLEAF) {
e.index = base;
*exactp = 0;
return (&e);
}
/*
* No match found. Base is the smallest index greater than
* key and may be zero or a last + 1 index. If it's non-zero,
* decrement by one, and record the internal page which should
* be a parent page for the key. If a split later occurs, the
* inserted page will be to the right of the saved page.
*/
index = base ? base - 1 : base;
next: if (__bt_push(t, h->pgno, index) == RET_ERROR)
return (NULL);
pg = GETBINTERNAL(h, index)->pgno;
mpool_put(t->bt_mp, h, 0);
}
}

View file

@ -0,0 +1,391 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: bt_seq.c /main/3 1996/06/11 17:13:05 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_seq.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <db.h>
#include "btree.h"
static int bt_seqadv __P((BTREE *, EPG *, int));
static int bt_seqset __P((BTREE *, EPG *, DBT *, int));
/*
* Sequential scan support.
*
* The tree can be scanned sequentially, starting from either end of the tree
* or from any specific key. A scan request before any scanning is done is
* initialized as starting from the least node.
*
* Each tree has an EPGNO which has the current position of the cursor. The
* cursor has to survive deletions/insertions in the tree without losing its
* position. This is done by noting deletions without doing them, and then
* doing them when the cursor moves (or the tree is closed).
*/
/*
* __BT_SEQ -- Btree sequential scan interface.
*
* Parameters:
* dbp: pointer to access method
* key: key for positioning and return value
* data: data return value
* flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
*
* Returns:
* RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
*/
int
__bt_seq(const DB *dbp, DBT *key, DBT *data, u_int flags)
{
BTREE *t;
EPG e;
int status;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
/*
* If scan unitialized as yet, or starting at a specific record, set
* the scan to a specific key. Both bt_seqset and bt_seqadv pin the
* page the cursor references if they're successful.
*/
switch(flags) {
case R_NEXT:
case R_PREV:
if (ISSET(t, B_SEQINIT)) {
status = bt_seqadv(t, &e, flags);
break;
}
/* FALLTHROUGH */
case R_CURSOR:
case R_FIRST:
case R_LAST:
status = bt_seqset(t, &e, key, flags);
break;
default:
errno = EINVAL;
return (RET_ERROR);
}
if (status == RET_SUCCESS) {
status = __bt_ret(t, &e, key, data);
/* Update the actual cursor. */
t->bt_bcursor.pgno = e.page->pgno;
t->bt_bcursor.index = e.index;
/*
* If the user is doing concurrent access, we copied the
* key/data, toss the page.
*/
if (ISSET(t, B_DB_LOCK))
mpool_put(t->bt_mp, e.page, 0);
else
t->bt_pinned = e.page;
SET(t, B_SEQINIT);
}
return (status);
}
/*
* BT_SEQSET -- Set the sequential scan to a specific key.
*
* Parameters:
* t: tree
* ep: storage for returned key
* key: key for initial scan position
* flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV
*
* Side effects:
* Pins the page the cursor references.
*
* Returns:
* RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
*/
static int
bt_seqset(BTREE *t, EPG *ep, DBT *key, int flags)
{
EPG *e;
PAGE *h;
pgno_t pg;
int exact;
/*
* Delete any already deleted record that we've been saving because
* the cursor pointed to it. Since going to a specific key, should
* delete any logically deleted records so they aren't found.
*/
if (ISSET(t, B_DELCRSR) && __bt_crsrdel(t, &t->bt_bcursor))
return (RET_ERROR);
/*
* Find the first, last or specific key in the tree and point the cursor
* at it. The cursor may not be moved until a new key has been found.
*/
switch(flags) {
case R_CURSOR: /* Keyed scan. */
/*
* Find the first instance of the key or the smallest key which
* is greater than or equal to the specified key. If run out
* of keys, return RET_SPECIAL.
*/
if (key->data == NULL || key->size == 0) {
errno = EINVAL;
return (RET_ERROR);
}
e = __bt_first(t, key, &exact); /* Returns pinned page. */
if (e == NULL)
return (RET_ERROR);
/*
* If at the end of a page, skip any empty pages and find the
* next entry.
*/
if (e->index == NEXTINDEX(e->page)) {
h = e->page;
do {
pg = h->nextpg;
mpool_put(t->bt_mp, h, 0);
if (pg == P_INVALID)
return (RET_SPECIAL);
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
} while (NEXTINDEX(h) == 0);
e->index = 0;
e->page = h;
}
*ep = *e;
break;
case R_FIRST: /* First record. */
case R_NEXT:
/* Walk down the left-hand side of the tree. */
for (pg = P_ROOT;;) {
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
if (h->flags & (P_BLEAF | P_RLEAF))
break;
pg = GETBINTERNAL(h, 0)->pgno;
mpool_put(t->bt_mp, h, 0);
}
/* Skip any empty pages. */
while (NEXTINDEX(h) == 0 && h->nextpg != P_INVALID) {
pg = h->nextpg;
mpool_put(t->bt_mp, h, 0);
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
}
if (NEXTINDEX(h) == 0) {
mpool_put(t->bt_mp, h, 0);
return (RET_SPECIAL);
}
ep->page = h;
ep->index = 0;
break;
case R_LAST: /* Last record. */
case R_PREV:
/* Walk down the right-hand side of the tree. */
for (pg = P_ROOT;;) {
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
if (h->flags & (P_BLEAF | P_RLEAF))
break;
pg = GETBINTERNAL(h, NEXTINDEX(h) - 1)->pgno;
mpool_put(t->bt_mp, h, 0);
}
/* Skip any empty pages. */
while (NEXTINDEX(h) == 0 && h->prevpg != P_INVALID) {
pg = h->prevpg;
mpool_put(t->bt_mp, h, 0);
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
}
if (NEXTINDEX(h) == 0) {
mpool_put(t->bt_mp, h, 0);
return (RET_SPECIAL);
}
ep->page = h;
ep->index = NEXTINDEX(h) - 1;
break;
}
return (RET_SUCCESS);
}
/*
* BT_SEQADVANCE -- Advance the sequential scan.
*
* Parameters:
* t: tree
* flags: R_NEXT, R_PREV
*
* Side effects:
* Pins the page the new key/data record is on.
*
* Returns:
* RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
*/
static int
bt_seqadv(BTREE *t, EPG *e, int flags)
{
EPGNO *c, delc;
PAGE *h;
indx_t index;
pgno_t pg;
/* Save the current cursor if going to delete it. */
c = &t->bt_bcursor;
if (ISSET(t, B_DELCRSR))
delc = *c;
if ((h = mpool_get(t->bt_mp, c->pgno, 0)) == NULL)
return (RET_ERROR);
/*
* Find the next/previous record in the tree and point the cursor at it.
* The cursor may not be moved until a new key has been found.
*/
index = c->index;
switch(flags) {
case R_NEXT: /* Next record. */
if (++index == NEXTINDEX(h)) {
do {
pg = h->nextpg;
mpool_put(t->bt_mp, h, 0);
if (pg == P_INVALID)
return (RET_SPECIAL);
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
} while (NEXTINDEX(h) == 0);
index = 0;
}
break;
case R_PREV: /* Previous record. */
if (index-- == 0) {
do {
pg = h->prevpg;
mpool_put(t->bt_mp, h, 0);
if (pg == P_INVALID)
return (RET_SPECIAL);
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
} while (NEXTINDEX(h) == 0);
index = NEXTINDEX(h) - 1;
}
break;
}
e->page = h;
e->index = index;
/*
* Delete any already deleted record that we've been saving because the
* cursor pointed to it. This could cause the new index to be shifted
* down by one if the record we're deleting is on the same page and has
* a larger index.
*/
if (ISSET(t, B_DELCRSR)) {
CLR(t, B_DELCRSR); /* Don't try twice. */
if (c->pgno == delc.pgno && c->index > delc.index)
--c->index;
if (__bt_crsrdel(t, &delc))
return (RET_ERROR);
}
return (RET_SUCCESS);
}
/*
* __BT_CRSRDEL -- Delete the record referenced by the cursor.
*
* Parameters:
* t: tree
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__bt_crsrdel(BTREE *t, EPGNO *c)
{
PAGE *h;
int status;
CLR(t, B_DELCRSR); /* Don't try twice. */
if ((h = mpool_get(t->bt_mp, c->pgno, 0)) == NULL)
return (RET_ERROR);
status = __bt_dleaf(t, h, c->index);
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
return (status);
}

View file

@ -0,0 +1,826 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: bt_split.c /main/3 1996/06/11 17:13:10 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_split.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#define __DBINTERFACE_PRIVATE
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
#include "btree.h"
static int bt_broot __P((BTREE *, PAGE *, PAGE *, PAGE *));
static PAGE *bt_page
__P((BTREE *, PAGE *, PAGE **, PAGE **, u_int *, size_t));
static int bt_preserve __P((BTREE *, pgno_t));
static PAGE *bt_psplit
__P((BTREE *, PAGE *, PAGE *, PAGE *, u_int *, size_t));
static PAGE *bt_root
__P((BTREE *, PAGE *, PAGE **, PAGE **, u_int *, size_t));
static int bt_rroot __P((BTREE *, PAGE *, PAGE *, PAGE *));
static recno_t rec_total __P((PAGE *));
#ifdef STATISTICS
u_long bt_rootsplit, bt_split, bt_sortsplit, bt_pfxsaved;
#endif
/*
* __BT_SPLIT -- Split the tree.
*
* Parameters:
* t: tree
* sp: page to split
* key: key to insert
* data: data to insert
* flags: BIGKEY/BIGDATA flags
* ilen: insert length
* skip: index to leave open
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__bt_split(BTREE *t, PAGE *sp, const DBT *key, const DBT *data, u_long flags, size_t ilen, u_int skip)
{
BINTERNAL *bi = NULL;
BLEAF *bl = NULL;
BLEAF *tbl;
DBT a, b;
EPGNO *parent;
PAGE *h, *l, *r, *lchild, *rchild;
indx_t nxtindex;
size_t n, nbytes;
size_t nksize = 0;
int parentsplit;
char *dest;
/*
* Split the page into two pages, l and r. The split routines return
* a pointer to the page into which the key should be inserted and with
* skip set to the offset which should be used. Additionally, l and r
* are pinned.
*/
h = sp->pgno == P_ROOT ?
bt_root(t, sp, &l, &r, &skip, ilen) :
bt_page(t, sp, &l, &r, &skip, ilen);
if (h == NULL)
return (RET_ERROR);
/*
* Insert the new key/data pair into the leaf page. (Key inserts
* always cause a leaf page to split first.)
*/
h->linp[skip] = h->upper -= ilen;
dest = (char *)h + h->upper;
if (ISSET(t, R_RECNO))
WR_RLEAF(dest, data, flags)
else
WR_BLEAF(dest, key, data, flags)
/* If the root page was split, make it look right. */
if (sp->pgno == P_ROOT &&
(ISSET(t, R_RECNO) ?
bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR)
goto err2;
/*
* Now we walk the parent page stack -- a LIFO stack of the pages that
* were traversed when we searched for the page that split. Each stack
* entry is a page number and a page index offset. The offset is for
* the page traversed on the search. We've just split a page, so we
* have to insert a new key into the parent page.
*
* If the insert into the parent page causes it to split, may have to
* continue splitting all the way up the tree. We stop if the root
* splits or the page inserted into didn't have to split to hold the
* new key. Some algorithms replace the key for the old page as well
* as the new page. We don't, as there's no reason to believe that the
* first key on the old page is any better than the key we have, and,
* in the case of a key being placed at index 0 causing the split, the
* key is unavailable.
*
* There are a maximum of 5 pages pinned at any time. We keep the left
* and right pages pinned while working on the parent. The 5 are the
* two children, left parent and right parent (when the parent splits)
* and the root page or the overflow key page when calling bt_preserve.
* This code must make sure that all pins are released other than the
* root page or overflow page which is unlocked elsewhere.
*/
while ((parent = BT_POP(t)) != NULL) {
lchild = l;
rchild = r;
/* Get the parent page. */
if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
goto err2;
/*
* The new key goes ONE AFTER the index, because the split
* was to the right.
*/
skip = parent->index + 1;
/*
* Calculate the space needed on the parent page.
*
* Prefix trees: space hack when inserting into BINTERNAL
* pages. Retain only what's needed to distinguish between
* the new entry and the LAST entry on the page to its left.
* If the keys compare equal, retain the entire key. Note,
* we don't touch overflow keys, and the entire key must be
* retained for the next-to-left most key on the leftmost
* page of each level, or the search will fail. Applicable
* ONLY to internal pages that have leaf pages as children.
* Further reduction of the key between pairs of internal
* pages loses too much information.
*/
switch (rchild->flags & P_TYPE) {
case P_BINTERNAL:
bi = GETBINTERNAL(rchild, 0);
nbytes = NBINTERNAL(bi->ksize);
break;
case P_BLEAF:
bl = GETBLEAF(rchild, 0);
nbytes = NBINTERNAL(bl->ksize);
if (t->bt_pfx && !(bl->flags & P_BIGKEY) &&
(h->prevpg != P_INVALID || skip > 1)) {
tbl = GETBLEAF(lchild, NEXTINDEX(lchild) - 1);
a.size = tbl->ksize;
a.data = tbl->bytes;
b.size = bl->ksize;
b.data = bl->bytes;
nksize = t->bt_pfx(&a, &b);
n = NBINTERNAL(nksize);
if (n < nbytes) {
#ifdef STATISTICS
bt_pfxsaved += nbytes - n;
#endif
nbytes = n;
} else
nksize = 0;
} else
nksize = 0;
break;
case P_RINTERNAL:
case P_RLEAF:
nbytes = NRINTERNAL;
break;
default:
abort();
}
/* Split the parent page if necessary or shift the indices. */
if (h->upper - h->lower < nbytes + sizeof(indx_t)) {
sp = h;
h = h->pgno == P_ROOT ?
bt_root(t, h, &l, &r, &skip, nbytes) :
bt_page(t, h, &l, &r, &skip, nbytes);
if (h == NULL)
goto err1;
parentsplit = 1;
} else {
if (skip < (nxtindex = NEXTINDEX(h)))
memmove(h->linp + skip + 1, h->linp + skip,
(nxtindex - skip) * sizeof(indx_t));
h->lower += sizeof(indx_t);
parentsplit = 0;
}
/* Insert the key into the parent page. */
switch(rchild->flags & P_TYPE) {
case P_BINTERNAL:
h->linp[skip] = h->upper -= nbytes;
dest = (char *)h + h->linp[skip];
memmove(dest, bi, nbytes);
((BINTERNAL *)dest)->pgno = rchild->pgno;
break;
case P_BLEAF:
h->linp[skip] = h->upper -= nbytes;
dest = (char *)h + h->linp[skip];
WR_BINTERNAL(dest, nksize ? nksize : bl->ksize,
rchild->pgno, bl->flags & P_BIGKEY);
memmove(dest, bl->bytes, nksize ? nksize : bl->ksize);
if (bl->flags & P_BIGKEY &&
bt_preserve(t, *(char *)bl->bytes) == RET_ERROR)
goto err1;
break;
case P_RINTERNAL:
/*
* Update the left page count. If split
* added at index 0, fix the correct page.
*/
if (skip > 0)
dest = (char *)h + h->linp[skip - 1];
else
dest = (char *)l + l->linp[NEXTINDEX(l) - 1];
((RINTERNAL *)dest)->nrecs = rec_total(lchild);
((RINTERNAL *)dest)->pgno = lchild->pgno;
/* Update the right page count. */
h->linp[skip] = h->upper -= nbytes;
dest = (char *)h + h->linp[skip];
((RINTERNAL *)dest)->nrecs = rec_total(rchild);
((RINTERNAL *)dest)->pgno = rchild->pgno;
break;
case P_RLEAF:
/*
* Update the left page count. If split
* added at index 0, fix the correct page.
*/
if (skip > 0)
dest = (char *)h + h->linp[skip - 1];
else
dest = (char *)l + l->linp[NEXTINDEX(l) - 1];
((RINTERNAL *)dest)->nrecs = NEXTINDEX(lchild);
((RINTERNAL *)dest)->pgno = lchild->pgno;
/* Update the right page count. */
h->linp[skip] = h->upper -= nbytes;
dest = (char *)h + h->linp[skip];
((RINTERNAL *)dest)->nrecs = NEXTINDEX(rchild);
((RINTERNAL *)dest)->pgno = rchild->pgno;
break;
default:
abort();
}
/* Unpin the held pages. */
if (!parentsplit) {
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
break;
}
/* If the root page was split, make it look right. */
if (sp->pgno == P_ROOT &&
(ISSET(t, R_RECNO) ?
bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR)
goto err1;
mpool_put(t->bt_mp, lchild, MPOOL_DIRTY);
mpool_put(t->bt_mp, rchild, MPOOL_DIRTY);
}
/* Unpin the held pages. */
mpool_put(t->bt_mp, l, MPOOL_DIRTY);
mpool_put(t->bt_mp, r, MPOOL_DIRTY);
/* Clear any pages left on the stack. */
return (RET_SUCCESS);
/*
* If something fails in the above loop we were already walking back
* up the tree and the tree is now inconsistent. Nothing much we can
* do about it but release any memory we're holding.
*/
err1: mpool_put(t->bt_mp, lchild, MPOOL_DIRTY);
mpool_put(t->bt_mp, rchild, MPOOL_DIRTY);
err2: mpool_put(t->bt_mp, l, 0);
mpool_put(t->bt_mp, r, 0);
__dbpanic(t->bt_dbp);
return (RET_ERROR);
}
/*
* BT_PAGE -- Split a non-root page of a btree.
*
* Parameters:
* t: tree
* h: root page
* lp: pointer to left page pointer
* rp: pointer to right page pointer
* skip: pointer to index to leave open
* ilen: insert length
*
* Returns:
* Pointer to page in which to insert or NULL on error.
*/
static PAGE *
bt_page(BTREE *t, PAGE *h, PAGE **lp, PAGE **rp, u_int *skip, size_t ilen)
{
PAGE *l, *r, *tp;
pgno_t npg;
#ifdef STATISTICS
++bt_split;
#endif
/* Put the new right page for the split into place. */
if ((r = __bt_new(t, &npg)) == NULL)
return (NULL);
r->pgno = npg;
r->lower = BTDATAOFF;
r->upper = t->bt_psize;
r->nextpg = h->nextpg;
r->prevpg = h->pgno;
r->flags = h->flags & P_TYPE;
/*
* If we're splitting the last page on a level because we're appending
* a key to it (skip is NEXTINDEX()), it's likely that the data is
* sorted. Adding an empty page on the side of the level is less work
* and can push the fill factor much higher than normal. If we're
* wrong it's no big deal, we'll just do the split the right way next
* time. It may look like it's equally easy to do a similar hack for
* reverse sorted data, that is, split the tree left, but it's not.
* Don't even try.
*/
if (h->nextpg == P_INVALID && *skip == NEXTINDEX(h)) {
#ifdef STATISTICS
++bt_sortsplit;
#endif
h->nextpg = r->pgno;
r->lower = BTDATAOFF + sizeof(indx_t);
*skip = 0;
*lp = h;
*rp = r;
return (r);
}
/* Put the new left page for the split into place. */
if ((l = malloc(t->bt_psize)) == NULL) {
mpool_put(t->bt_mp, r, 0);
return (NULL);
}
l->pgno = h->pgno;
l->nextpg = r->pgno;
l->prevpg = h->prevpg;
l->lower = BTDATAOFF;
l->upper = t->bt_psize;
l->flags = h->flags & P_TYPE;
/* Fix up the previous pointer of the page after the split page. */
if (h->nextpg != P_INVALID) {
if ((tp = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) {
free(l);
/* XXX mpool_free(t->bt_mp, r->pgno); */
return (NULL);
}
tp->prevpg = r->pgno;
mpool_put(t->bt_mp, tp, 0);
}
/*
* Split right. The key/data pairs aren't sorted in the btree page so
* it's simpler to copy the data from the split page onto two new pages
* instead of copying half the data to the right page and compacting
* the left page in place. Since the left page can't change, we have
* to swap the original and the allocated left page after the split.
*/
tp = bt_psplit(t, h, l, r, skip, ilen);
/* Move the new left page onto the old left page. */
memmove(h, l, t->bt_psize);
if (tp == l)
tp = h;
free(l);
*lp = h;
*rp = r;
return (tp);
}
/*
* BT_ROOT -- Split the root page of a btree.
*
* Parameters:
* t: tree
* h: root page
* lp: pointer to left page pointer
* rp: pointer to right page pointer
* skip: pointer to index to leave open
* ilen: insert length
*
* Returns:
* Pointer to page in which to insert or NULL on error.
*/
static PAGE *
bt_root(BTREE *t, PAGE *h, PAGE **lp, PAGE **rp, u_int *skip, size_t ilen)
{
PAGE *l, *r, *tp;
pgno_t lnpg, rnpg;
#ifdef STATISTICS
++bt_split;
++bt_rootsplit;
#endif
/* Put the new left and right pages for the split into place. */
if ((l = __bt_new(t, &lnpg)) == NULL ||
(r = __bt_new(t, &rnpg)) == NULL)
return (NULL);
l->pgno = lnpg;
r->pgno = rnpg;
l->nextpg = r->pgno;
r->prevpg = l->pgno;
l->prevpg = r->nextpg = P_INVALID;
l->lower = r->lower = BTDATAOFF;
l->upper = r->upper = t->bt_psize;
l->flags = r->flags = h->flags & P_TYPE;
/* Split the root page. */
tp = bt_psplit(t, h, l, r, skip, ilen);
*lp = l;
*rp = r;
return (tp);
}
/*
* BT_RROOT -- Fix up the recno root page after it has been split.
*
* Parameters:
* t: tree
* h: root page
* l: left page
* r: right page
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
static int
bt_rroot(BTREE *t, PAGE *h, PAGE *l, PAGE *r)
{
char *dest;
/* Insert the left and right keys, set the header information. */
h->linp[0] = h->upper = t->bt_psize - NRINTERNAL;
dest = (char *)h + h->upper;
WR_RINTERNAL(dest,
l->flags & P_RLEAF ? NEXTINDEX(l) : rec_total(l), l->pgno);
h->linp[1] = h->upper -= NRINTERNAL;
dest = (char *)h + h->upper;
WR_RINTERNAL(dest,
r->flags & P_RLEAF ? NEXTINDEX(r) : rec_total(r), r->pgno);
h->lower = BTDATAOFF + 2 * sizeof(indx_t);
/* Unpin the root page, set to recno internal page. */
h->flags &= ~P_TYPE;
h->flags |= P_RINTERNAL;
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
return (RET_SUCCESS);
}
/*
* BT_BROOT -- Fix up the btree root page after it has been split.
*
* Parameters:
* t: tree
* h: root page
* l: left page
* r: right page
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
static int
bt_broot(BTREE *t, PAGE *h, PAGE *l, PAGE *r)
{
BINTERNAL *bi;
BLEAF *bl;
size_t nbytes;
char *dest;
/*
* If the root page was a leaf page, change it into an internal page.
* We copy the key we split on (but not the key's data, in the case of
* a leaf page) to the new root page.
*
* The btree comparison code guarantees that the left-most key on any
* level of the tree is never used, so it doesn't need to be filled in.
*/
nbytes = NBINTERNAL(0);
h->linp[0] = h->upper = t->bt_psize - nbytes;
dest = (char *)h + h->upper;
WR_BINTERNAL(dest, 0, l->pgno, 0);
switch(h->flags & P_TYPE) {
case P_BLEAF:
bl = GETBLEAF(r, 0);
nbytes = NBINTERNAL(bl->ksize);
h->linp[1] = h->upper -= nbytes;
dest = (char *)h + h->upper;
WR_BINTERNAL(dest, bl->ksize, r->pgno, 0);
memmove(dest, bl->bytes, bl->ksize);
/*
* If the key is on an overflow page, mark the overflow chain
* so it isn't deleted when the leaf copy of the key is deleted.
*/
if (bl->flags & P_BIGKEY &&
bt_preserve(t, *(char *)bl->bytes) == RET_ERROR)
return (RET_ERROR);
break;
case P_BINTERNAL:
bi = GETBINTERNAL(r, 0);
nbytes = NBINTERNAL(bi->ksize);
h->linp[1] = h->upper -= nbytes;
dest = (char *)h + h->upper;
memmove(dest, bi, nbytes);
((BINTERNAL *)dest)->pgno = r->pgno;
break;
default:
abort();
}
/* There are two keys on the page. */
h->lower = BTDATAOFF + 2 * sizeof(indx_t);
/* Unpin the root page, set to btree internal page. */
h->flags &= ~P_TYPE;
h->flags |= P_BINTERNAL;
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
return (RET_SUCCESS);
}
/*
* BT_PSPLIT -- Do the real work of splitting the page.
*
* Parameters:
* t: tree
* h: page to be split
* l: page to put lower half of data
* r: page to put upper half of data
* pskip: pointer to index to leave open
* ilen: insert length
*
* Returns:
* Pointer to page in which to insert.
*/
static PAGE *
bt_psplit(BTREE *t, PAGE *h, PAGE *l, PAGE *r, u_int *pskip, size_t ilen)
{
BINTERNAL *bi;
BLEAF *bl;
RLEAF *rl;
EPGNO *c;
PAGE *rval;
void *src = NULL;
indx_t full, half, nxt, off, skip, top, used;
size_t nbytes;
int bigkeycnt, isbigkey;
/*
* Split the data to the left and right pages. Leave the skip index
* open. Additionally, make some effort not to split on an overflow
* key. This makes internal page processing faster and can save
* space as overflow keys used by internal pages are never deleted.
*/
bigkeycnt = 0;
skip = *pskip;
full = t->bt_psize - BTDATAOFF;
half = full / 2;
used = 0;
for (nxt = off = 0, top = NEXTINDEX(h); nxt < top; ++off) {
if (skip == off) {
nbytes = ilen;
isbigkey = 0; /* XXX: not really known. */
} else
switch (h->flags & P_TYPE) {
case P_BINTERNAL:
src = bi = GETBINTERNAL(h, nxt);
nbytes = NBINTERNAL(bi->ksize);
isbigkey = bi->flags & P_BIGKEY;
break;
case P_BLEAF:
src = bl = GETBLEAF(h, nxt);
nbytes = NBLEAF(bl);
isbigkey = bl->flags & P_BIGKEY;
break;
case P_RINTERNAL:
src = GETRINTERNAL(h, nxt);
nbytes = NRINTERNAL;
isbigkey = 0;
break;
case P_RLEAF:
src = rl = GETRLEAF(h, nxt);
nbytes = NRLEAF(rl);
isbigkey = 0;
break;
default:
abort();
}
/*
* If the key/data pairs are substantial fractions of the max
* possible size for the page, it's possible to get situations
* where we decide to try and copy too much onto the left page.
* Make sure that doesn't happen.
*/
if (skip <= off && used + nbytes >= full) {
--off;
break;
}
/* Copy the key/data pair, if not the skipped index. */
if (skip != off) {
++nxt;
l->linp[off] = l->upper -= nbytes;
memmove((char *)l + l->upper, src, nbytes);
}
used += nbytes;
if (used >= half) {
if (!isbigkey || bigkeycnt == 3)
break;
else
++bigkeycnt;
}
}
/*
* Off is the last offset that's valid for the left page.
* Nxt is the first offset to be placed on the right page.
*/
l->lower += (off + 1) * sizeof(indx_t);
/*
* If splitting the page that the cursor was on, the cursor has to be
* adjusted to point to the same record as before the split. If the
* cursor is at or past the skipped slot, the cursor is incremented by
* one. If the cursor is on the right page, it is decremented by the
* number of records split to the left page.
*
* Don't bother checking for the B_SEQINIT flag, the page number will
* be P_INVALID.
*/
c = &t->bt_bcursor;
if (c->pgno == h->pgno) {
if (c->index >= skip)
++c->index;
if (c->index < nxt) /* Left page. */
c->pgno = l->pgno;
else { /* Right page. */
c->pgno = r->pgno;
c->index -= nxt;
}
}
/*
* If the skipped index was on the left page, just return that page.
* Otherwise, adjust the skip index to reflect the new position on
* the right page.
*/
if (skip <= off) {
skip = 0;
rval = l;
} else {
rval = r;
*pskip -= nxt;
}
for (off = 0; nxt < top; ++off) {
if (skip == nxt) {
++off;
skip = 0;
}
switch (h->flags & P_TYPE) {
case P_BINTERNAL:
src = bi = GETBINTERNAL(h, nxt);
nbytes = NBINTERNAL(bi->ksize);
break;
case P_BLEAF:
src = bl = GETBLEAF(h, nxt);
nbytes = NBLEAF(bl);
break;
case P_RINTERNAL:
src = GETRINTERNAL(h, nxt);
nbytes = NRINTERNAL;
break;
case P_RLEAF:
src = rl = GETRLEAF(h, nxt);
nbytes = NRLEAF(rl);
break;
default:
abort();
}
++nxt;
r->linp[off] = r->upper -= nbytes;
memmove((char *)r + r->upper, src, nbytes);
}
r->lower += off * sizeof(indx_t);
/* If the key is being appended to the page, adjust the index. */
if (skip == top)
r->lower += sizeof(indx_t);
return (rval);
}
/*
* BT_PRESERVE -- Mark a chain of pages as used by an internal node.
*
* Chains of indirect blocks pointed to by leaf nodes get reclaimed when the
* record that references them gets deleted. Chains pointed to by internal
* pages never get deleted. This routine marks a chain as pointed to by an
* internal page.
*
* Parameters:
* t: tree
* pg: page number of first page in the chain.
*
* Returns:
* RET_SUCCESS, RET_ERROR.
*/
static int
bt_preserve(BTREE *t, pgno_t pg)
{
PAGE *h;
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
h->flags |= P_PRESERVE;
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
return (RET_SUCCESS);
}
/*
* REC_TOTAL -- Return the number of recno entries below a page.
*
* Parameters:
* h: page
*
* Returns:
* The number of recno entries below a page.
*
* XXX
* These values could be set by the bt_psplit routine. The problem is that the
* entry has to be popped off of the stack etc. or the values have to be passed
* all the way back to bt_split/bt_rroot and it's not very clean.
*/
static recno_t
rec_total(PAGE *h)
{
recno_t recs;
indx_t nxt, top;
for (recs = 0, nxt = 0, top = NEXTINDEX(h); nxt < top; ++nxt)
recs += GETRINTERNAL(h, nxt)->nrecs;
return (recs);
}

View file

@ -0,0 +1,112 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: bt_stack.c /main/3 1996/06/11 17:13:15 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_stack.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <db.h>
#include "btree.h"
/*
* When a page splits, a new record has to be inserted into its parent page.
* This page may have to split as well, all the way up to the root. Since
* parent pointers in each page would be expensive, we maintain a stack of
* parent pages as we descend the tree.
*
* XXX
* This is a concurrency problem -- if user a builds a stack, then user b
* splits the tree, then user a tries to split the tree, there's a new level
* in the tree that user a doesn't know about.
*/
/*
* __BT_PUSH -- Push parent page info onto the stack (LIFO).
*
* Parameters:
* t: tree
* pgno: page
* index: page index
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__bt_push(BTREE *t, pgno_t pgno, int index)
{
if (t->bt_sp == t->bt_maxstack) {
t->bt_maxstack += 50;
if ((t->bt_stack = __fix_realloc(t->bt_stack,
t->bt_maxstack * sizeof(EPGNO))) == NULL) {
t->bt_maxstack -= 50;
return (RET_ERROR);
}
}
t->bt_stack[t->bt_sp].pgno = pgno;
t->bt_stack[t->bt_sp].index = index;
++t->bt_sp;
return (RET_SUCCESS);
}

View file

@ -0,0 +1,255 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: bt_utils.c /main/3 1996/06/11 17:13:20 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_utils.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
#include "btree.h"
/*
* __BT_RET -- Build return key/data pair as a result of search or scan.
*
* Parameters:
* t: tree
* d: LEAF to be returned to the user.
* key: user's key structure (NULL if not to be filled in)
* data: user's data structure
*
* Returns:
* RET_SUCCESS, RET_ERROR.
*/
int
__bt_ret(BTREE *t, EPG *e, DBT *key, DBT *data)
{
BLEAF *bl;
void *p;
bl = GETBLEAF(e->page, e->index);
/*
* We always copy big keys/data to make them contigous. Otherwise,
* we leave the page pinned and don't copy unless the user specified
* concurrent access.
*/
if (bl->flags & P_BIGDATA) {
if (__ovfl_get(t, bl->bytes + bl->ksize,
&data->size, &t->bt_dbuf, &t->bt_dbufsz))
return (RET_ERROR);
data->data = t->bt_dbuf;
} else if (ISSET(t, B_DB_LOCK)) {
/* Use +1 in case the first record retrieved is 0 length. */
if (bl->dsize + 1 > t->bt_dbufsz) {
if ((p = __fix_realloc(t->bt_dbuf, bl->dsize + 1)) == NULL)
return (RET_ERROR);
t->bt_dbuf = p;
t->bt_dbufsz = bl->dsize + 1;
}
memmove(t->bt_dbuf, bl->bytes + bl->ksize, bl->dsize);
data->size = bl->dsize;
data->data = t->bt_dbuf;
} else {
data->size = bl->dsize;
data->data = bl->bytes + bl->ksize;
}
if (key == NULL)
return (RET_SUCCESS);
if (bl->flags & P_BIGKEY) {
if (__ovfl_get(t, bl->bytes,
&key->size, &t->bt_kbuf, &t->bt_kbufsz))
return (RET_ERROR);
key->data = t->bt_kbuf;
} else if (ISSET(t, B_DB_LOCK)) {
if (bl->ksize > t->bt_kbufsz) {
if ((p = __fix_realloc(t->bt_kbuf, bl->ksize)) == NULL)
return (RET_ERROR);
t->bt_kbuf = p;
t->bt_kbufsz = bl->ksize;
}
memmove(t->bt_kbuf, bl->bytes, bl->ksize);
key->size = bl->ksize;
key->data = t->bt_kbuf;
} else {
key->size = bl->ksize;
key->data = bl->bytes;
}
return (RET_SUCCESS);
}
/*
* __BT_CMP -- Compare a key to a given record.
*
* Parameters:
* t: tree
* k1: DBT pointer of first arg to comparison
* e: pointer to EPG for comparison
*
* Returns:
* < 0 if k1 is < record
* = 0 if k1 is = record
* > 0 if k1 is > record
*/
int
__bt_cmp(BTREE *t, const DBT *k1, EPG *e)
{
BINTERNAL *bi;
BLEAF *bl;
DBT k2;
PAGE *h;
void *bigkey;
/*
* The left-most key on internal pages, at any level of the tree, is
* guaranteed by the following code to be less than any user key.
* This saves us from having to update the leftmost key on an internal
* page when the user inserts a new key in the tree smaller than
* anything we've yet seen.
*/
h = e->page;
if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF))
return (1);
bigkey = NULL;
if (h->flags & P_BLEAF) {
bl = GETBLEAF(h, e->index);
if (bl->flags & P_BIGKEY)
bigkey = bl->bytes;
else {
k2.data = bl->bytes;
k2.size = bl->ksize;
}
} else {
bi = GETBINTERNAL(h, e->index);
if (bi->flags & P_BIGKEY)
bigkey = bi->bytes;
else {
k2.data = bi->bytes;
k2.size = bi->ksize;
}
}
if (bigkey) {
if (__ovfl_get(t, bigkey,
&k2.size, &t->bt_dbuf, &t->bt_dbufsz))
return (RET_ERROR);
k2.data = t->bt_dbuf;
}
return ((*t->bt_cmp)(k1, &k2));
}
/*
* __BT_DEFCMP -- Default comparison routine.
*
* Parameters:
* a: DBT #1
* b: DBT #2
*
* Returns:
* < 0 if a is < b
* = 0 if a is = b
* > 0 if a is > b
*/
int
__bt_defcmp(const DBT *a, const DBT *b)
{
u_char *p1, *p2;
int diff, len;
len = MIN(a->size, b->size);
for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2)
if ((diff = *p1 - *p2))
return (diff);
return (a->size - b->size);
}
/*
* __BT_DEFPFX -- Default prefix routine.
*
* Parameters:
* a: DBT #1
* b: DBT #2
*
* Returns:
* Number of bytes needed to distinguish b from a.
*/
int
__bt_defpfx(const DBT *a, const DBT *b)
{
u_char *p1, *p2;
int len;
int cnt;
cnt = 1;
len = MIN(a->size, b->size);
for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt)
if (*p1 != *p2)
return (cnt);
/* a->size must be <= b->size, or they wouldn't be in this order. */
return (a->size < b->size ? a->size + 1 : a->size);
}

View file

@ -0,0 +1,374 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: btree.h /main/5 1996/07/18 16:31:58 drk $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)btree.h 8.2 (Berkeley) 9/7/93
*/
#include <mpool.h>
#define DEFMINKEYPAGE (2) /* Minimum keys per page */
#define MINCACHE (5) /* Minimum cached pages */
#define MINPSIZE (512) /* Minimum page size */
/*
* Page 0 of a btree file contains a copy of the meta-data. This page is also
* used as an out-of-band page, i.e. page pointers that point to nowhere point
* to page 0. Page 1 is the root of the btree.
*/
#define P_INVALID 0 /* Invalid tree page number. */
#define P_META 0 /* Tree metadata page number. */
#define P_ROOT 1 /* Tree root page number. */
/*
* There are five page layouts in the btree: btree internal pages (BINTERNAL),
* btree leaf pages (BLEAF), recno internal pages (RINTERNAL), recno leaf pages
* (RLEAF) and overflow pages. All five page types have a page header (PAGE).
* This implementation requires that longs within structures are NOT padded.
* (ANSI C permits random padding.) If your compiler pads randomly you'll have
* to do some work to get this package to run.
*/
typedef struct _page {
pgno_t pgno; /* this page's page number */
pgno_t prevpg; /* left sibling */
pgno_t nextpg; /* right sibling */
#define P_BINTERNAL 0x01 /* btree internal page */
#define P_BLEAF 0x02 /* leaf page */
#define P_OVERFLOW 0x04 /* overflow page */
#define P_RINTERNAL 0x08 /* recno internal page */
#define P_RLEAF 0x10 /* leaf page */
#define P_TYPE 0x1f /* type mask */
#define P_PRESERVE 0x20 /* never delete this chain of pages */
u_long flags;
indx_t lower; /* lower bound of free space on page */
indx_t upper; /* upper bound of free space on page */
indx_t linp[1]; /* long-aligned VARIABLE LENGTH DATA */
} PAGE;
/* First and next index. */
#define BTDATAOFF (sizeof(pgno_t) + sizeof(pgno_t) + sizeof(pgno_t) + \
sizeof(u_long) + sizeof(indx_t) + sizeof(indx_t))
#define NEXTINDEX(p) (((p)->lower - BTDATAOFF) / sizeof(indx_t))
/*
* For pages other than overflow pages, there is an array of offsets into the
* rest of the page immediately following the page header. Each offset is to
* an item which is unique to the type of page. The h_lower offset is just
* past the last filled-in index. The h_upper offset is the first item on the
* page. Offsets are from the beginning of the page.
*
* If an item is too big to store on a single page, a flag is set and the item
* is a { page, size } pair such that the page is the first page of an overflow
* chain with size bytes of item. Overflow pages are simply bytes without any
* external structure.
*
* The size and page number fields in the items are long aligned so they can be
* manipulated without copying.
*/
#define LALIGN(n) (((n) + sizeof(u_long) - 1) & ~(sizeof(u_long) - 1))
#define NOVFLSIZE (sizeof(pgno_t) + sizeof(size_t))
/*
* For the btree internal pages, the item is a key. BINTERNALs are {key, pgno}
* pairs, such that the key compares less than or equal to all of the records
* on that page. For a tree without duplicate keys, an internal page with two
* consecutive keys, a and b, will have all records greater than or equal to a
* and less than b stored on the page associated with a. Duplicate keys are
* somewhat special and can cause duplicate internal and leaf page records and
* some minor modifications of the above rule.
*/
typedef struct _binternal {
size_t ksize; /* key size */
pgno_t pgno; /* page number stored on */
#define P_BIGDATA 0x01 /* overflow data */
#define P_BIGKEY 0x02 /* overflow key */
u_char flags;
char bytes[1]; /* data */
} BINTERNAL;
/* Get the page's BINTERNAL structure at index indx. */
#define GETBINTERNAL(pg, indx) \
((BINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
/* Get the number of bytes in the entry. */
#define NBINTERNAL(len) \
LALIGN(sizeof(size_t) + sizeof(pgno_t) + sizeof(u_char) + (len))
/* Copy a BINTERNAL entry to the page. */
#define WR_BINTERNAL(p, size, pgno, flags) { \
*(size_t *)p = size; \
p += sizeof(size_t); \
*(pgno_t *)p = pgno; \
p += sizeof(pgno_t); \
*(u_char *)p = flags; \
p += sizeof(u_char); \
}
/*
* For the recno internal pages, the item is a page number with the number of
* keys found on that page and below.
*/
typedef struct _rinternal {
recno_t nrecs; /* number of records */
pgno_t pgno; /* page number stored below */
} RINTERNAL;
/* Get the page's RINTERNAL structure at index indx. */
#define GETRINTERNAL(pg, indx) \
((RINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
/* Get the number of bytes in the entry. */
#define NRINTERNAL \
LALIGN(sizeof(recno_t) + sizeof(pgno_t))
/* Copy a RINTERAL entry to the page. */
#define WR_RINTERNAL(p, nrecs, pgno) { \
*(recno_t *)p = nrecs; \
p += sizeof(recno_t); \
*(pgno_t *)p = pgno; \
}
/* For the btree leaf pages, the item is a key and data pair. */
typedef struct _bleaf {
size_t ksize; /* size of key */
size_t dsize; /* size of data */
u_char flags; /* P_BIGDATA, P_BIGKEY */
char bytes[1]; /* data */
} BLEAF;
/* Get the page's BLEAF structure at index indx. */
#define GETBLEAF(pg, indx) \
((BLEAF *)((char *)(pg) + (pg)->linp[indx]))
/* Get the number of bytes in the entry. */
#define NBLEAF(p) NBLEAFDBT((p)->ksize, (p)->dsize)
/* Get the number of bytes in the user's key/data pair. */
#define NBLEAFDBT(ksize, dsize) \
LALIGN(sizeof(size_t) + sizeof(size_t) + sizeof(u_char) + \
(ksize) + (dsize))
/* Copy a BLEAF entry to the page. */
#define WR_BLEAF(p, key, data, flags) { \
*(size_t *)p = key->size; \
p += sizeof(size_t); \
*(size_t *)p = data->size; \
p += sizeof(size_t); \
*(u_char *)p = flags; \
p += sizeof(u_char); \
memmove(p, key->data, key->size); \
p += key->size; \
memmove(p, data->data, data->size); \
}
/* For the recno leaf pages, the item is a data entry. */
typedef struct _rleaf {
size_t dsize; /* size of data */
u_char flags; /* P_BIGDATA */
char bytes[1];
} RLEAF;
/* Get the page's RLEAF structure at index indx. */
#define GETRLEAF(pg, indx) \
((RLEAF *)((char *)(pg) + (pg)->linp[indx]))
/* Get the number of bytes in the entry. */
#define NRLEAF(p) NRLEAFDBT((p)->dsize)
/* Get the number of bytes from the user's data. */
#define NRLEAFDBT(dsize) \
LALIGN(sizeof(size_t) + sizeof(u_char) + (dsize))
/* Copy a RLEAF entry to the page. */
#define WR_RLEAF(p, data, flags) { \
*(size_t *)p = data->size; \
p += sizeof(size_t); \
*(u_char *)p = flags; \
p += sizeof(u_char); \
memmove(p, data->data, data->size); \
}
/*
* A record in the tree is either a pointer to a page and an index in the page
* or a page number and an index. These structures are used as a cursor, stack
* entry and search returns as well as to pass records to other routines.
*
* One comment about searches. Internal page searches must find the largest
* record less than key in the tree so that descents work. Leaf page searches
* must find the smallest record greater than key so that the returned index
* is the record's correct position for insertion.
*
* One comment about cursors. The cursor key is never removed from the tree,
* even if deleted. This is because it is quite difficult to decide where the
* cursor should be when other keys have been inserted/deleted in the tree;
* duplicate keys make it impossible. This scheme does require extra work
* though, to make sure that we don't perform an operation on a deleted key.
*/
typedef struct _epgno {
pgno_t pgno; /* the page number */
indx_t index; /* the index on the page */
} EPGNO;
typedef struct _epg {
PAGE *page; /* the (pinned) page */
indx_t index; /* the index on the page */
} EPG;
/*
* The metadata of the tree. The m_nrecs field is used only by the RECNO code.
* This is because the btree doesn't really need it and it requires that every
* put or delete call modify the metadata.
*/
typedef struct _btmeta {
u_long m_magic; /* magic number */
u_long m_version; /* version */
u_long m_psize; /* page size */
u_long m_free; /* page number of first free page */
u_long m_nrecs; /* R: number of records */
#define SAVEMETA (B_NODUPS | R_RECNO)
u_long m_flags; /* bt_flags & SAVEMETA */
u_long m_unused; /* unused */
} BTMETA;
/* The in-memory btree/recno data structure. */
typedef struct _btree {
MPOOL *bt_mp; /* memory pool cookie */
DB *bt_dbp; /* pointer to enclosing DB */
PAGE *bt_pinned; /* page pinned across calls */
EPGNO bt_bcursor; /* B: btree cursor */
recno_t bt_rcursor; /* R: recno cursor (1-based) */
#define BT_POP(t) (t->bt_sp ? t->bt_stack + --t->bt_sp : NULL)
#define BT_CLR(t) (t->bt_sp = 0)
EPGNO *bt_stack; /* stack of parent pages */
u_int bt_sp; /* current stack pointer */
u_int bt_maxstack; /* largest stack */
char *bt_kbuf; /* key buffer */
size_t bt_kbufsz; /* key buffer size */
char *bt_dbuf; /* data buffer */
size_t bt_dbufsz; /* data buffer size */
int bt_fd; /* tree file descriptor */
pgno_t bt_free; /* next free page */
u_long bt_psize; /* page size */
indx_t bt_ovflsize; /* cut-off for key/data overflow */
int bt_lorder; /* byte order */
/* sorted order */
enum { NOT, BACK, FORWARD } bt_order;
EPGNO bt_last; /* last insert */
/* B: key comparison function */
int (*bt_cmp) __P((const DBT *, const DBT *));
/* B: prefix comparison function */
int (*bt_pfx) __P((const DBT *, const DBT *));
/* R: recno input function */
int (*bt_irec) __P((struct _btree *, recno_t));
FILE *bt_rfp; /* R: record FILE pointer */
int bt_rfd; /* R: record file descriptor */
caddr_t bt_cmap; /* R: current point in mapped space */
caddr_t bt_smap; /* R: start of mapped space */
caddr_t bt_emap; /* R: end of mapped space */
size_t bt_msize; /* R: size of mapped region. */
recno_t bt_nrecs; /* R: number of records */
size_t bt_reclen; /* R: fixed record length */
u_char bt_bval; /* R: delimiting byte/pad character */
/*
* NB:
* B_NODUPS and R_RECNO are stored on disk, and may not be changed.
*/
#define B_DELCRSR 0x00001 /* cursor has been deleted */
#define B_INMEM 0x00002 /* in-memory tree */
#define B_METADIRTY 0x00004 /* need to write metadata */
#define B_MODIFIED 0x00008 /* tree modified */
#define B_NEEDSWAP 0x00010 /* if byte order requires swapping */
#define B_NODUPS 0x00020 /* no duplicate keys permitted */
#define B_RDONLY 0x00040 /* read-only tree */
#define R_RECNO 0x00080 /* record oriented tree */
#define B_SEQINIT 0x00100 /* sequential scan initialized */
#define R_CLOSEFP 0x00200 /* opened a file pointer */
#define R_EOF 0x00400 /* end of input file reached. */
#define R_FIXLEN 0x00800 /* fixed length records */
#define R_MEMMAPPED 0x01000 /* memory mapped file. */
#define R_INMEM 0x02000 /* in-memory file */
#define R_MODIFIED 0x04000 /* modified file */
#define R_RDONLY 0x08000 /* read-only file */
#define B_DB_LOCK 0x10000 /* DB_LOCK specified. */
#define B_DB_SHMEM 0x20000 /* DB_SHMEM specified. */
#define B_DB_TXN 0x40000 /* DB_TXN specified. */
u_long bt_flags; /* btree state */
} BTREE;
#define SET(t, f) ((t)->bt_flags |= (f))
#define CLR(t, f) ((t)->bt_flags &= ~(f))
#define ISSET(t, f) ((t)->bt_flags & (f))
#include "extern.h"

View file

@ -0,0 +1,134 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: cdefs.h /main/4 1996/06/11 17:13:31 cde-hal $ */
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)cdefs.h 8.1 (Berkeley) 6/2/93
*/
#ifndef _CDEFS_H_
#define _CDEFS_H_
#if defined(__cplusplus)
#ifndef __BEGIN_DECLS
#define __BEGIN_DECLS extern "C" {
#endif
#ifndef __END_DECLS
#define __END_DECLS };
#endif
#else
#undef __BEGIN_DECLS
#define __BEGIN_DECLS
#undef __END_DECLS
#define __END_DECLS
#endif
/*
* The __CONCAT macro is used to concatenate parts of symbol names, e.g.
* with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
* The __CONCAT macro is a bit tricky -- make sure you don't put spaces
* in between its arguments. __CONCAT can also concatenate double-quoted
* strings produced by the __STRING macro, but this only works with ANSI C.
*/
#if defined(__STDC__) || defined(__cplusplus)
#ifdef __P
#undef __P
#endif
#define __P(protos) protos /* full-blown ANSI C */
#ifndef __CONCAT
#define __CONCAT(x,y) x ## y
#endif
#define __STRING(x) #x
#else /* !(__STDC__ || __cplusplus) */
#ifdef __P
#undef __P
#endif
#define __P(protos) () /* traditional C preprocessor */
#define __CONCAT(x,y) x/**/y
#define __STRING(x) "x"
#ifdef __GNUC__
#define const __const /* GCC: ANSI C with -traditional */
#define inline __inline
#define signed __signed
#define volatile __volatile
#else /* !__GNUC__ */
#define const /* delete ANSI C keywords */
#define inline
#define signed
#define volatile
#endif /* !__GNUC__ */
#endif /* !(__STDC__ || __cplusplus) */
/*
* GCC has extensions for declaring functions as `pure' (always returns
* the same value given the same inputs, i.e., has no external state and
* no side effects) and `dead' (nonreturning). These mainly affect
* optimization and warnings. Unfortunately, GCC complains if these are
* used under strict ANSI mode (`gcc -ansi -pedantic'), hence we need to
* define them only if compiling without this.
*/
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
#undef __dead
#define __dead __volatile
#ifndef __pure
#define __pure __const
#endif
#else
#define __dead
#define __pure
#endif
#endif /* !_CDEFS_H_ */

View file

@ -0,0 +1,254 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: compat.h /main/8 1996/07/18 16:32:14 drk $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)compat.h 8.3 (Berkeley) 9/6/93
*/
#ifndef _COMPAT_H_
#define _COMPAT_H_
#include <sys/types.h>
#include "utility/config.h"
/*
* If your system doesn't typedef u_long, u_short, or u_char, change
* the 0 to a 1.
*/
#if 0
typedef unsigned long u_long;
typedef unsigned short u_short;
typedef unsigned char u_char;
#endif
/* If your system doesn't typedef size_t, change the 0 to a 1. */
#if 0
typedef unsigned int size_t;
#endif
/*
* If your system doesn't have the POSIX type for a signal mask,
* change the 0 to a 1.
*/
#if 0
typedef unsigned int sigset_t;
#endif
/*
* If you don't have POSIX 1003.1 signals, the signal code surrounding the
* temporary file creation is intended to block all of the possible signals
* long enough to create the file and unlink it. All of this stuff is
* intended to use old-style BSD calls to fake POSIX 1003.1 calls.
*/
#ifdef NO_POSIX_SIGNALS
#define sigemptyset(set) (*(set) = 0)
#define sigfillset(set) (*(set) = ~(sigset_t)0, 0)
#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0)
#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0)
#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0)
#define SIG_BLOCK 1
#define SIG_UNBLOCK 2
#define SIG_SETMASK 3
static int __sigtemp; /* For the use of sigprocmask */
/* Repeated test of oset != NULL is to avoid "*0". */
#define sigprocmask(how, set, oset) \
((__sigtemp = \
(((how) == SIG_BLOCK) ? \
sigblock(0) | *(set) : \
(((how) == SIG_UNBLOCK) ? \
sigblock(0) & ~(*(set)) : \
((how) == SIG_SETMASK ? \
*(set) : sigblock(0))))), \
((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : \
sigsetmask(__sigtemp)), 0)
#endif
/*
* If realloc(3) of a NULL pointer on your system isn't the same as
* a malloc(3) call, change the 0 to a 1, and add realloc.o to the
* MISC line in your Makefile.
*/
/*
#if 1
#define realloc __fix_realloc
#endif
*/
void * __fix_realloc __P((void*, size_t));
/*
* If your system doesn't have an include file with the appropriate
* byte order set, make sure you specify the correct one.
*/
#ifndef BYTE_ORDER
#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */
#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */
#ifdef MMDB_LITTLE_ENDIAN
#define BYTE_ORDER LITTLE_ENDIAN /* Set for your system. */
#endif
#ifdef MMDB_BIG_ENDIAN
#define BYTE_ORDER BIG_ENDIAN /* Set for your system. */
#endif
#endif
#if defined(SYSV) || defined(SYSTEM5) || defined(SVR4)
/* #define index(a, b) strchr(a, b) */
#ifndef rindex
#define rindex(a, b) strrchr(a, b)
#endif
#define bzero(a, b) memset(a, 0, b)
#define bcmp(a, b, n) memcmp(a, b, n)
#define bcopy(a, b, n) memmove(b, a, n)
#endif
#if defined(BSD) || defined(BSD4_3)
#define strchr(a, b) index(a, b)
#define strrchr(a, b) rindex(a, b)
#define memcmp(a, b, n) bcmp(a, b, n)
#define memmove(a, b, n) bcopy(b, a, n)
#endif
/*
* 32-bit machine. The db routines are theoretically independent of
* the size of u_shorts and u_longs, but I don't know that anyone has
* ever actually tried it. At a minimum, change the following #define's
* if you are trying to compile on a different type of system.
*/
#ifndef USHRT_MAX
#define USHRT_MAX 0xFFFF
#define ULONG_MAX 0xFFFFFFFF
#endif
/* POSIX 1003.1 access mode mask. */
#ifndef O_ACCMODE
#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
#endif
/* POSIX 1003.2 RE limit. */
#ifndef _POSIX2_RE_DUP_MAX
#define _POSIX2_RE_DUP_MAX 255
#endif
/*
* If you can't provide lock values in the open(2) call. Note, this
* allows races to happen.
*/
#ifndef O_EXLOCK
#define O_EXLOCK 0
#endif
#ifndef O_SHLOCK
#define O_SHLOCK 0
#endif
#ifndef EFTYPE
#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */
#endif
#ifndef WCOREDUMP /* 4.4BSD extension */
#define WCOREDUMP(a) 0
#endif
#ifndef STDERR_FILENO
#define STDIN_FILENO 0 /* ANSI C #defines */
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif
#ifndef SEEK_END
#define SEEK_SET 0 /* POSIX 1003.1 seek values */
#define SEEK_CUR 1
#define SEEK_END 2
#endif
#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */
#define S_ISLNK(m) ((m & 0170000) == 0120000)
#define S_ISSOCK(m) ((m & 0170000) == 0140000)
#endif
#ifndef TCSASOFT
#define TCSASOFT 0
#endif
#ifndef _POSIX2_RE_DUP_MAX
#define _POSIX2_RE_DUP_MAX 255
#endif
#ifndef NULL /* ANSI C #defines NULL everywhere. */
#define NULL 0
#endif
#undef MAX
#define MAX(a,b) ((a)<(b)?(b):(a))
#undef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#ifndef DEFFILEMODE /* Default file permissions. */
#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
#endif
#ifndef _BSD_VA_LIST_
#define _BSD_VA_LIST_ char *
#endif
#endif /* !_COMPAT_H_ */

View file

@ -0,0 +1,122 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: db.c /main/3 1996/06/11 17:13:41 cde-hal $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)db.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdio.h>
#define __DBINTERFACE_PRIVATE
#include <db.h>
DB *
dbopen(const char *fname, int flags, int mode, DBTYPE type, const void *openinfo)
{
#define DB_FLAGS (DB_LOCK | DB_SHMEM | DB_TXN)
#define USE_OPEN_FLAGS \
(O_CREAT | O_EXCL | O_EXLOCK | O_RDONLY | O_RDWR | \
O_SHLOCK | O_TRUNC)
if ((flags & ~(USE_OPEN_FLAGS | DB_FLAGS)) == 0)
switch (type) {
case DB_BTREE:
return (__bt_open(fname, flags & USE_OPEN_FLAGS,
mode, openinfo, flags & DB_FLAGS));
/*
case DB_HASH:
return (__hash_open(fname, flags & USE_OPEN_FLAGS,
mode, openinfo, flags & DB_FLAGS));
case DB_RECNO:
return (__rec_open(fname, flags & USE_OPEN_FLAGS,
mode, openinfo, flags & DB_FLAGS));
*/
default:
break;
}
errno = EINVAL;
return (NULL);
}
static int
__dberr(void)
{
return (RET_ERROR);
}
/*
* __DBPANIC -- Stop.
*
* Parameters:
* dbp: pointer to the DB structure.
*/
void
__dbpanic(DB *dbp)
{
/* The only thing that can succeed is a close. */
dbp->del = (int (*)())__dberr;
dbp->fd = (int (*)())__dberr;
dbp->get = (int (*)())__dberr;
dbp->put = (int (*)())__dberr;
dbp->seq = (int (*)())__dberr;
dbp->sync = (int (*)())__dberr;
}

View file

@ -0,0 +1,249 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: db.h /main/3 1996/06/11 17:13:46 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)db.h 8.2 (Berkeley) 9/7/93
*/
#ifndef _DB_H_
#define _DB_H_
#include <sys/types.h>
#include "cdefs.h"
#include <limits.h>
#include "compat.h"
#define RET_ERROR -1 /* Return values. */
#define RET_SUCCESS 0
#define RET_SPECIAL 1
#define MAX_PAGE_NUMBER ULONG_MAX /* >= # of pages in a file */
typedef u_long pgno_t;
#define MAX_PAGE_OFFSET USHRT_MAX /* >= # of bytes in a page */
typedef u_short indx_t;
#define MAX_REC_NUMBER ULONG_MAX /* >= # of records in a tree */
typedef u_long recno_t;
/* Key/data structure -- a Data-Base Thang. */
typedef struct {
void *data; /* data */
size_t size; /* data length */
} DBT;
/* Routine flags. */
#define R_CURSOR 1 /* del, put, seq */
#define __R_UNUSED 2 /* UNUSED */
#define R_FIRST 3 /* seq */
#define R_IAFTER 4 /* put (RECNO) */
#define R_IBEFORE 5 /* put (RECNO) */
#define R_LAST 6 /* seq (BTREE, RECNO) */
#define R_NEXT 7 /* seq */
#define R_NOOVERWRITE 8 /* put */
#define R_PREV 9 /* seq (BTREE, RECNO) */
#define R_SETCURSOR 10 /* put (RECNO) */
#define R_RECNOSYNC 11 /* sync (RECNO) */
typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
/*
* !!!
* The following flags are included in the dbopen(3) call as part of the
* open(2) flags. In order to avoid conflicts with the open flags, start
* at the top of the 16 or 32-bit number space and work our way down. If
* the open flags were significantly expanded in the future, it could be
* a problem. Wish I'd left another flags word in the dbopen call.
*
* !!!
* None of this stuff is implemented yet. The only reason that it's here
* is so that the access methods can skip copying the key/data pair when
* the DB_LOCK flag isn't set.
*/
/*
assume 32 bit UINT.
*/
/*
#if UINT_MAX > 65535
*/
#define DB_LOCK 0x20000000 /* Do locking. */
#define DB_SHMEM 0x40000000 /* Use shared memory. */
#define DB_TXN 0x80000000 /* Do transactions. */
/*
#else
#define DB_LOCK 0x00002000
#define DB_SHMEM 0x00004000
#define DB_TXN 0x00008000
#endif
*/
/* Access method description structure. */
typedef struct __db {
DBTYPE type; /* Underlying db type. */
int (*close) __P((struct __db *));
int (*del) __P((const struct __db *, const DBT *, u_int));
int (*fd) __P((const struct __db *));
int (*get) __P((const struct __db *, const DBT *, DBT *, u_int));
int (*put) __P((const struct __db *, DBT *, const DBT *, u_int));
int (*seq) __P((const struct __db *, DBT *, DBT *, u_int));
int (*sync) __P((const struct __db *, u_int));
void *internal; /* access method private */
} DB;
#define BTREEMAGIC 0x053162
#define BTREEVERSION 3
/* Structure used to pass parameters to the btree routines. */
typedef struct {
#define R_DUP 0x01 /* duplicate keys */
u_long flags;
int cachesize; /* bytes to cache */
int maxkeypage; /* maximum keys per page */
int minkeypage; /* minimum keys per page */
int psize; /* page size */
/* comparison, prefix functions */
int (*compare) __P((const DBT *, const DBT *));
int (*prefix) __P((const DBT *, const DBT *));
int lorder; /* byte order */
} BTREEINFO;
#define HASHMAGIC 0x061561
#define HASHVERSION 2
/* Structure used to pass parameters to the hashing routines. */
typedef struct {
int bsize; /* bucket size */
int ffactor; /* fill factor */
int nelem; /* number of elements */
int cachesize; /* bytes to cache */
/* hash function */
int (*hash) __P((const void *, size_t));
int lorder; /* byte order */
} HASHINFO;
/* Structure used to pass parameters to the record routines. */
typedef struct {
#define R_FIXEDLEN 0x01 /* fixed-length records */
#define R_NOKEY 0x02 /* key not required */
#define R_SNAPSHOT 0x04 /* snapshot the input */
u_long flags;
int cachesize; /* bytes to cache */
int psize; /* page size */
int lorder; /* byte order */
size_t reclen; /* record length (fixed-length records) */
u_char bval; /* delimiting byte (variable-length records */
char *bfname; /* btree file name */
} RECNOINFO;
/*
* Little endian <==> big endian long swap macros.
* BLSWAP swap a memory location
* BLPSWAP swap a referenced memory location
* BLSWAP_COPY swap from one location to another
*/
#define BLSWAP(a) { \
u_long _tmp = a; \
((char *)&a)[0] = ((char *)&_tmp)[3]; \
((char *)&a)[1] = ((char *)&_tmp)[2]; \
((char *)&a)[2] = ((char *)&_tmp)[1]; \
((char *)&a)[3] = ((char *)&_tmp)[0]; \
}
#define BLPSWAP(a) { \
u_long _tmp = *(u_long *)a; \
((char *)a)[0] = ((char *)&_tmp)[3]; \
((char *)a)[1] = ((char *)&_tmp)[2]; \
((char *)a)[2] = ((char *)&_tmp)[1]; \
((char *)a)[3] = ((char *)&_tmp)[0]; \
}
#define BLSWAP_COPY(a, b) { \
((char *)&(b))[0] = ((char *)&(a))[3]; \
((char *)&(b))[1] = ((char *)&(a))[2]; \
((char *)&(b))[2] = ((char *)&(a))[1]; \
((char *)&(b))[3] = ((char *)&(a))[0]; \
}
/*
* Little endian <==> big endian short swap macros.
* BSSWAP swap a memory location
* BSPSWAP swap a referenced memory location
* BSSWAP_COPY swap from one location to another
*/
#define BSSWAP(a) { \
u_short _tmp = a; \
((char *)&a)[0] = ((char *)&_tmp)[1]; \
((char *)&a)[1] = ((char *)&_tmp)[0]; \
}
#define BSPSWAP(a) { \
u_short _tmp = *(u_short *)a; \
((char *)a)[0] = ((char *)&_tmp)[1]; \
((char *)a)[1] = ((char *)&_tmp)[0]; \
}
#define BSSWAP_COPY(a, b) { \
((char *)&(b))[0] = ((char *)&(a))[1]; \
((char *)&(b))[1] = ((char *)&(a))[0]; \
}
__BEGIN_DECLS
DB *dbopen __P((const char *, int, int, DBTYPE, const void *));
#ifdef __DBINTERFACE_PRIVATE
DB *__bt_open __P((const char *, int, int, const BTREEINFO *, int));
DB *__hash_open __P((const char *, int, int, const HASHINFO *, int));
DB *__rec_open __P((const char *, int, int, const RECNOINFO *, int));
void __dbpanic __P((DB *dbp));
#endif
__END_DECLS
#endif /* !_DB_H_ */

View file

@ -0,0 +1,93 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: extern.h /main/3 1996/06/11 17:13:51 cde-hal $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)extern.h 8.2 (Berkeley) 9/7/93
*/
int __bt_close __P((DB *));
int __bt_cmp __P((BTREE *, const DBT *, EPG *));
int __bt_crsrdel __P((BTREE *, EPGNO *));
int __bt_defcmp __P((const DBT *, const DBT *));
int __bt_defpfx __P((const DBT *, const DBT *));
int __bt_delete __P((const DB *, const DBT *, u_int));
int __bt_dleaf __P((BTREE *, PAGE *, int));
int __bt_fd __P((const DB *));
EPG *__bt_first __P((BTREE *, const DBT *, int *));
int __bt_free __P((BTREE *, PAGE *));
int __bt_get __P((const DB *, const DBT *, DBT *, u_int));
PAGE *__bt_new __P((BTREE *, pgno_t *));
void __bt_pgin __P((void *, pgno_t, void *));
void __bt_pgout __P((void *, pgno_t, void *));
int __bt_push __P((BTREE *, pgno_t, int));
int __bt_put __P((const DB *dbp, DBT *, const DBT *, u_int));
int __bt_ret __P((BTREE *, EPG *, DBT *, DBT *));
EPG *__bt_search __P((BTREE *, const DBT *, int *));
int __bt_seq __P((const DB *, DBT *, DBT *, u_int));
int __bt_split __P((BTREE *, PAGE *,
const DBT *, const DBT *, u_long, size_t, u_int));
int __bt_sync __P((const DB *, u_int));
int __ovfl_delete __P((BTREE *, void *));
int __ovfl_get __P((BTREE *, void *, size_t *, char **, size_t *));
int __ovfl_put __P((BTREE *, const DBT *, pgno_t *));
#ifdef DEBUG
void __bt_dnpage __P((DB *, pgno_t));
void __bt_dpage __P((PAGE *));
void __bt_dump __P((DB *));
#endif
#ifdef STATISTICS
void __bt_stat __P((DB *));
#endif

View file

@ -0,0 +1,162 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: memmove.c /main/3 1996/06/11 17:13:55 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include "cdefs.h"
#include <string.h>
/*
* sizeof(word) MUST BE A POWER OF TWO
* SO THAT wmask BELOW IS ALL ONES
*/
typedef int word; /* "word" used for optimal copy speed */
#define wsize sizeof(word)
#define wmask (wsize - 1)
/*
* Copy a block of memory, handling overlap.
* This is the routine that actually implements
* (the portable versions of) bcopy, memcpy, and memmove.
*/
#ifdef MEMCOPY
void *
memcpy(dst0, src0, length)
#else
#ifdef MEMMOVE
void *
memmove(dst0, src0, length)
#else
void
bcopy(src0, dst0, length)
#endif
#endif
void *dst0;
const void *src0;
size_t length;
{
char *dst = dst0;
const char *src = src0;
size_t t;
if (length == 0 || dst == src) /* nothing to do */
goto done;
/*
* Macros: loop-t-times; and loop-t-times, t>0
*/
#define TLOOP(s) if (t) TLOOP1(s)
#define TLOOP1(s) do { s; } while (--t)
if ((unsigned long)dst < (unsigned long)src) {
/*
* Copy forward.
*/
t = (size_t)src; /* only need low bits */
if ((t | (size_t)dst) & wmask) {
/*
* Try to align operands. This cannot be done
* unless the low bits match.
*/
if ((t ^ (size_t)dst) & wmask || length < wsize)
t = length;
else
t = wsize - (t & wmask);
length -= t;
TLOOP1(*dst++ = *src++);
}
/*
* Copy whole words, then mop up any trailing bytes.
*/
t = length / wsize;
TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
t = length & wmask;
TLOOP(*dst++ = *src++);
} else {
/*
* Copy backwards. Otherwise essentially the same.
* Alignment works as before, except that it takes
* (t&wmask) bytes to align, not wsize-(t&wmask).
*/
src += length;
dst += length;
t = (size_t)src;
if ((t | (size_t)dst) & wmask) {
if ((t ^ (size_t)dst) & wmask || length <= wsize)
t = length;
else
t &= wmask;
length -= t;
TLOOP1(*--dst = *--src);
}
t = length / wsize;
TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
t = length & wmask;
TLOOP(*--dst = *--src);
}
done:
#if defined(MEMCOPY) || defined(MEMMOVE)
return (dst0);
#else
return;
#endif
}

View file

@ -0,0 +1,150 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: mktemp.c /main/4 1996/11/01 10:18:53 drk $ */
/*
* Copyright (c) 1987, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
#include <X11/Xosdefs.h>
#ifdef X_NOT_STDC_ENV
extern int errno;
#endif
static int _gettemp(char*, int*);
int mkstemp(char *path)
{
int fd;
return (_gettemp(path, &fd) ? fd : -1);
}
char *
mktemp(char *path)
{
return(_gettemp(path, (int *)NULL) ? path : (char *)NULL);
}
static int
_gettemp(char *path, int *doopen)
{
char *start, *trv;
struct stat sbuf;
u_int pid;
pid = getpid();
for (trv = path; *trv; ++trv); /* extra X's get set to 0's */
while (*--trv == 'X') {
*trv = (pid % 10) + '0';
pid /= 10;
}
/*
* check the target directory; if you have six X's and it
* doesn't exist this runs for a *very* long time.
*/
for (start = trv + 1;; --trv) {
if (trv <= path)
break;
if (*trv == '/') {
*trv = '\0';
if (stat(path, &sbuf))
return(0);
if (!S_ISDIR(sbuf.st_mode)) {
errno = ENOTDIR;
return(0);
}
*trv = '/';
break;
}
}
for (;;) {
if (doopen) {
if ((*doopen =
open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
return(1);
if (errno != EEXIST)
return(0);
}
else if (stat(path, &sbuf))
return(errno == ENOENT ? 1 : 0);
/* tricky little algorithm for backward compatibility */
for (trv = start;;) {
if (!*trv)
return(0);
if (*trv == 'z')
*trv++ = 'a';
else {
if (isdigit((unsigned char) *trv))
*trv = 'a';
else
++*trv;
break;
}
}
}
/*NOTREACHED*/
}

View file

@ -0,0 +1,542 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: mpool.c /main/4 1996/10/04 09:47:13 drk $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)mpool.c 8.1 (Berkeley) 6/6/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <db.h>
#define __MPOOLINTERFACE_PRIVATE
#include "mpool.h"
static BKT *mpool_bkt __P((MPOOL *));
static BKT *mpool_look __P((MPOOL *, pgno_t));
static int mpool_write __P((MPOOL *, BKT *));
#ifdef DEBUG
static void __mpoolerr __P((const char *fmt, ...));
#endif
/*
* MPOOL_OPEN -- initialize a memory pool.
*
* Parameters:
* key: Shared buffer key.
* fd: File descriptor.
* pagesize: File page size.
* maxcache: Max number of cached pages.
*
* Returns:
* MPOOL pointer, NULL on error.
*/
MPOOL *
mpool_open(DBT *key, int fd, pgno_t pagesize, pgno_t maxcache)
{
struct stat sb;
MPOOL *mp;
int entry;
if (fstat(fd, &sb))
return (NULL);
/* XXX
* We should only set st_size to 0 for pipes -- 4.4BSD has the fix so
* that stat(2) returns true for ISSOCK on pipes. Until then, this is
* fairly close.
*/
if (!S_ISREG(sb.st_mode)) {
errno = ESPIPE;
return (NULL);
}
if ((mp = malloc(sizeof(MPOOL))) == NULL)
return (NULL);
mp->free.cnext = mp->free.cprev = (BKT *)(void *)&mp->free;
mp->lru.cnext = mp->lru.cprev = (BKT *)(void *)&mp->lru;
for (entry = 0; entry < HASHSIZE; ++entry)
mp->hashtable[entry].hnext = mp->hashtable[entry].hprev =
mp->hashtable[entry].cnext = mp->hashtable[entry].cprev =
(BKT *)&mp->hashtable[entry];
mp->curcache = 0;
mp->maxcache = maxcache;
mp->pagesize = pagesize;
mp->npages = sb.st_size / pagesize;
mp->fd = fd;
mp->pgcookie = NULL;
mp->pgin = mp->pgout = NULL;
#ifdef STATISTICS
mp->cachehit = mp->cachemiss = mp->pagealloc = mp->pageflush =
mp->pageget = mp->pagenew = mp->pageput = mp->pageread =
mp->pagewrite = 0;
#endif
return (mp);
}
/*
* MPOOL_FILTER -- initialize input/output filters.
*
* Parameters:
* pgin: Page in conversion routine.
* pgout: Page out conversion routine.
* pgcookie: Cookie for page in/out routines.
*/
void
mpool_filter(MPOOL *mp,
void (*pgin) __P((void *, pgno_t, void *)),
void (*pgout) __P((void *, pgno_t, void *)),
void *pgcookie)
{
mp->pgin = pgin;
mp->pgout = pgout;
mp->pgcookie = pgcookie;
}
/*
* MPOOL_NEW -- get a new page
*
* Parameters:
* mp: mpool cookie
* pgnoadddr: place to store new page number
* Returns:
* RET_ERROR, RET_SUCCESS
*/
void *
mpool_new(MPOOL *mp, pgno_t *pgnoaddr)
{
BKT *b;
BKTHDR *hp;
#ifdef STATISTICS
++mp->pagenew;
#endif
/*
* Get a BKT from the cache. Assign a new page number, attach it to
* the hash and lru chains and return.
*/
if ((b = mpool_bkt(mp)) == NULL)
return (NULL);
*pgnoaddr = b->pgno = mp->npages++;
b->flags = MPOOL_PINNED;
inshash(b, b->pgno);
inschain(b, &mp->lru);
return (b->page);
}
/*
* MPOOL_GET -- get a page from the pool
*
* Parameters:
* mp: mpool cookie
* pgno: page number
* flags: not used
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
void *
mpool_get(MPOOL *mp, pgno_t pgno, u_int flags /* XXX not used? */)
{
BKT *b;
BKTHDR *hp;
off_t off;
int nr;
/*
* If asking for a specific page that is already in the cache, find
* it and return it.
*/
if ((b = mpool_look(mp, pgno))) {
#ifdef STATISTICS
++mp->pageget;
#endif
#ifdef DEBUG
if (b->flags & MPOOL_PINNED)
__mpoolerr("mpool_get: page %d already pinned",
b->pgno);
#endif
rmchain(b);
inschain(b, &mp->lru);
b->flags |= MPOOL_PINNED;
return (b->page);
}
/* Not allowed to retrieve a non-existent page. */
if (pgno >= mp->npages) {
errno = EINVAL;
return (NULL);
}
/* Get a page from the cache. */
if ((b = mpool_bkt(mp)) == NULL)
return (NULL);
b->pgno = pgno;
b->flags = MPOOL_PINNED;
#ifdef STATISTICS
++mp->pageread;
#endif
/* Read in the contents. */
off = mp->pagesize * pgno;
if (lseek(mp->fd, off, SEEK_SET) != off)
return (NULL);
if ((nr = read(mp->fd, b->page, mp->pagesize)) != mp->pagesize) {
if (nr >= 0)
errno = EFTYPE;
return (NULL);
}
if (mp->pgin)
(mp->pgin)(mp->pgcookie, b->pgno, b->page);
inshash(b, b->pgno);
inschain(b, &mp->lru);
#ifdef STATISTICS
++mp->pageget;
#endif
return (b->page);
}
/*
* MPOOL_PUT -- return a page to the pool
*
* Parameters:
* mp: mpool cookie
* page: page pointer
* pgno: page number
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
mpool_put(MPOOL *mp, void *page, u_int flags)
{
BKT *baddr;
#ifdef DEBUG
BKT *b;
#endif
#ifdef STATISTICS
++mp->pageput;
#endif
baddr = (BKT *)((char *)page - sizeof(BKT));
#ifdef DEBUG
if (!(baddr->flags & MPOOL_PINNED))
__mpoolerr("mpool_put: page %d not pinned", b->pgno);
for (b = mp->lru.cnext; b != (BKT *)&mp->lru; b = b->cnext) {
if (b == (BKT *)&mp->lru)
__mpoolerr("mpool_put: %0x: bad address", baddr);
if (b == baddr)
break;
}
#endif
baddr->flags &= ~MPOOL_PINNED;
baddr->flags |= flags & MPOOL_DIRTY;
return (RET_SUCCESS);
}
/*
* MPOOL_CLOSE -- close the buffer pool
*
* Parameters:
* mp: mpool cookie
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
mpool_close(MPOOL *mp)
{
BKT *b, *next;
/* Free up any space allocated to the lru pages. */
for (b = mp->lru.cprev; b != (BKT *)(void *)&mp->lru; b = next) {
next = b->cprev;
free(b);
}
free(mp);
return (RET_SUCCESS);
}
/*
* MPOOL_SYNC -- sync the file to disk.
*
* Parameters:
* mp: mpool cookie
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
mpool_sync(MPOOL *mp)
{
BKT *b;
for (b = mp->lru.cprev; b != (BKT *)(void *)&mp->lru; b = b->cprev)
if (b->flags & MPOOL_DIRTY && mpool_write(mp, b) == RET_ERROR)
return (RET_ERROR);
return (fsync(mp->fd) ? RET_ERROR : RET_SUCCESS);
}
/*
* MPOOL_BKT -- get/create a BKT from the cache
*
* Parameters:
* mp: mpool cookie
*
* Returns:
* NULL on failure and a pointer to the BKT on success
*/
static BKT *
mpool_bkt(MPOOL *mp)
{
BKT *b;
if (mp->curcache < mp->maxcache)
goto new;
/*
* If the cache is maxxed out, search the lru list for a buffer we
* can flush. If we find one, write it if necessary and take it off
* any lists. If we don't find anything we grow the cache anyway.
* The cache never shrinks.
*/
for (b = mp->lru.cprev; b != (BKT *)(void *)&mp->lru; b = b->cprev)
if (!(b->flags & MPOOL_PINNED)) {
if (b->flags & MPOOL_DIRTY &&
mpool_write(mp, b) == RET_ERROR)
return (NULL);
rmhash(b);
rmchain(b);
#ifdef STATISTICS
++mp->pageflush;
#endif
#ifdef DEBUG
{
void *spage;
spage = b->page;
memset(b, 0xff, sizeof(BKT) + mp->pagesize);
b->page = spage;
}
#endif
return (b);
}
new: if ((b = malloc(sizeof(BKT) + mp->pagesize)) == NULL)
return (NULL);
#ifdef STATISTICS
++mp->pagealloc;
#endif
/*
#ifdef DEBUG
*/
memset(b, 0xff, sizeof(BKT) + mp->pagesize);
/*
#endif
*/
b->page = (char *)b + sizeof(BKT);
++mp->curcache;
return (b);
}
/*
* MPOOL_WRITE -- sync a page to disk
*
* Parameters:
* mp: mpool cookie
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
static int
mpool_write(MPOOL *mp, BKT *b)
{
off_t off;
if (mp->pgout)
(mp->pgout)(mp->pgcookie, b->pgno, b->page);
#ifdef STATISTICS
++mp->pagewrite;
#endif
off = mp->pagesize * b->pgno;
if (lseek(mp->fd, off, SEEK_SET) != off)
return (RET_ERROR);
if (write(mp->fd, b->page, mp->pagesize) != mp->pagesize)
return (RET_ERROR);
b->flags &= ~MPOOL_DIRTY;
return (RET_SUCCESS);
}
/*
* MPOOL_LOOK -- lookup a page
*
* Parameters:
* mp: mpool cookie
* pgno: page number
*
* Returns:
* NULL on failure and a pointer to the BKT on success
*/
static BKT *
mpool_look(MPOOL *mp, pgno_t pgno)
{
BKT *b;
BKTHDR *tb;
/* XXX
* If find the buffer, put it first on the hash chain so can
* find it again quickly.
*/
tb = &mp->hashtable[HASHKEY(pgno)];
for (b = tb->hnext; b != (BKT *)tb; b = b->hnext)
if (b->pgno == pgno) {
#ifdef STATISTICS
++mp->cachehit;
#endif
return (b);
}
#ifdef STATISTICS
++mp->cachemiss;
#endif
return (NULL);
}
#ifdef STATISTICS
/*
* MPOOL_STAT -- cache statistics
*
* Parameters:
* mp: mpool cookie
*/
void
mpool_stat(MPOOL *mp)
{
BKT *b;
int cnt;
char *sep;
(void)fprintf(stderr, "%lu pages in the file\n", mp->npages);
(void)fprintf(stderr,
"page size %lu, cacheing %lu pages of %lu page max cache\n",
mp->pagesize, mp->curcache, mp->maxcache);
(void)fprintf(stderr, "%lu page puts, %lu page gets, %lu page new\n",
mp->pageput, mp->pageget, mp->pagenew);
(void)fprintf(stderr, "%lu page allocs, %lu page flushes\n",
mp->pagealloc, mp->pageflush);
if (mp->cachehit + mp->cachemiss)
(void)fprintf(stderr,
"%.0f%% cache hit rate (%lu hits, %lu misses)\n",
((double)mp->cachehit / (mp->cachehit + mp->cachemiss))
* 100, mp->cachehit, mp->cachemiss);
(void)fprintf(stderr, "%lu page reads, %lu page writes\n",
mp->pageread, mp->pagewrite);
sep = "";
cnt = 0;
for (b = mp->lru.cnext; b != (BKT *)&mp->lru; b = b->cnext) {
(void)fprintf(stderr, "%s%ld", sep, b->pgno);
if (b->flags & MPOOL_DIRTY)
(void)fprintf(stderr, "d");
if (b->flags & MPOOL_PINNED)
(void)fprintf(stderr, "P");
if (++cnt == 10) {
sep = "\n";
cnt = 0;
} else
sep = ", ";
}
(void)fprintf(stderr, "\n");
}
#endif
#ifdef DEBUG
#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
static void
#if __STDC__
__mpoolerr(const char *fmt, ...)
#else
__mpoolerr(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
va_list ap;
#if __STDC__
va_start(ap, fmt);
#else
va_start(ap);
#endif
(void)vfprintf(stderr, fmt, ap);
va_end(ap);
(void)fprintf(stderr, "\n");
abort();
/* NOTREACHED */
}
#endif

View file

@ -0,0 +1,158 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: mpool.h /main/3 1996/06/11 17:14:12 cde-hal $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)mpool.h 8.1 (Berkeley) 6/2/93
*/
/*
* The memory pool scheme is a simple one. Each in memory page is referenced
* by a bucket which is threaded in three ways. All active pages are threaded
* on a hash chain (hashed by the page number) and an lru chain. Inactive
* pages are threaded on a free chain. Each reference to a memory pool is
* handed an MPOOL which is the opaque cookie passed to all of the memory
* routines.
*/
#define HASHSIZE 128
#define HASHKEY(pgno) ((pgno - 1) % HASHSIZE)
/* The BKT structures are the elements of the lists. */
typedef struct BKT {
struct BKT *hnext; /* next hash bucket */
struct BKT *hprev; /* previous hash bucket */
struct BKT *cnext; /* next free/lru bucket */
struct BKT *cprev; /* previous free/lru bucket */
void *page; /* page */
pgno_t pgno; /* page number */
#define MPOOL_DIRTY 0x01 /* page needs to be written */
#define MPOOL_PINNED 0x02 /* page is pinned into memory */
unsigned long flags; /* flags */
} BKT;
/* The BKTHDR structures are the heads of the lists. */
typedef struct BKTHDR {
struct BKT *hnext; /* next hash bucket */
struct BKT *hprev; /* previous hash bucket */
struct BKT *cnext; /* next free/lru bucket */
struct BKT *cprev; /* previous free/lru bucket */
} BKTHDR;
typedef struct MPOOL {
BKTHDR free; /* The free list. */
BKTHDR lru; /* The LRU list. */
BKTHDR hashtable[HASHSIZE]; /* Hashed list by page number. */
pgno_t curcache; /* Current number of cached pages. */
pgno_t maxcache; /* Max number of cached pages. */
pgno_t npages; /* Number of pages in the file. */
u_long pagesize; /* File page size. */
int fd; /* File descriptor. */
/* Page in conversion routine. */
void (*pgin) __P((void *, pgno_t, void *));
/* Page out conversion routine. */
void (*pgout) __P((void *, pgno_t, void *));
void *pgcookie; /* Cookie for page in/out routines. */
#ifdef STATISTICS
unsigned long cachehit;
unsigned long cachemiss;
unsigned long pagealloc;
unsigned long pageflush;
unsigned long pageget;
unsigned long pagenew;
unsigned long pageput;
unsigned long pageread;
unsigned long pagewrite;
#endif
} MPOOL;
#ifdef __MPOOLINTERFACE_PRIVATE
/* Macros to insert/delete into/from hash chain. */
#define rmhash(bp) { \
(bp)->hprev->hnext = (bp)->hnext; \
(bp)->hnext->hprev = (bp)->hprev; \
}
#define inshash(bp, pg) { \
hp = &mp->hashtable[HASHKEY(pg)]; \
(bp)->hnext = hp->hnext; \
(bp)->hprev = (struct BKT *)hp; \
hp->hnext->hprev = (bp); \
hp->hnext = (bp); \
}
/* Macros to insert/delete into/from lru and free chains. */
#define rmchain(bp) { \
(bp)->cprev->cnext = (bp)->cnext; \
(bp)->cnext->cprev = (bp)->cprev; \
}
#define inschain(bp, dp) { \
(bp)->cnext = (dp)->cnext; \
(bp)->cprev = (struct BKT *)(void *)(dp); \
(dp)->cnext->cprev = (bp); \
(dp)->cnext = (bp); \
}
#endif
__BEGIN_DECLS
MPOOL *mpool_open __P((DBT *, int, pgno_t, pgno_t));
void mpool_filter __P((MPOOL *, void (*)(void *, pgno_t, void *),
void (*)(void *, pgno_t, void *), void *));
void *mpool_new __P((MPOOL *, pgno_t *));
void *mpool_get __P((MPOOL *, pgno_t, u_int));
int mpool_put __P((MPOOL *, void *, u_int));
int mpool_sync __P((MPOOL *));
int mpool_close __P((MPOOL *));
#ifdef STATISTICS
void mpool_stat __P((MPOOL *));
#endif
__END_DECLS

View file

@ -0,0 +1,100 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: ndbm.h /main/3 1996/06/11 17:14:17 cde-hal $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ndbm.h 8.1 (Berkeley) 6/2/93
*/
#ifndef _NDBM_H_
#define _NDBM_H_
#include <db.h>
/* Map dbm interface onto db(3). */
#define DBM_RDONLY O_RDONLY
/* Flags to dbm_store(). */
#define DBM_INSERT 0
#define DBM_REPLACE 1
/*
* The db(3) support for ndbm(3) always appends this suffix to the
* file name to avoid overwriting the user's original database.
*/
#define DBM_SUFFIX ".db"
typedef struct {
char *dptr;
int dsize;
} datum;
typedef DB DBM;
#define dbm_pagfno(a) DBM_PAGFNO_NOT_AVAILABLE
__BEGIN_DECLS
void dbm_close __P((DBM *));
int dbm_delete __P((DBM *, datum));
datum dbm_fetch __P((DBM *, datum));
datum dbm_firstkey __P((DBM *));
long dbm_forder __P((DBM *, datum));
datum dbm_nextkey __P((DBM *));
DBM *dbm_open __P((const char *, int, int));
int dbm_store __P((DBM *, datum, datum, int));
int dbm_dirfno __P((DBM *));
__END_DECLS
#endif /* !_NDBM_H_ */

View file

@ -1,9 +1,7 @@
/*
* CDE - Common Desktop Environment
*
* (c) Copyright 1993-2012 The Open Group
* (c) Copyright 2012-2022 CDE Project contributors, see
* CONTRIBUTORS for details
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
@ -22,11 +20,13 @@
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: realloc.c /main/3 1996/06/11 17:14:22 cde-hal $ */
#include <sys/types.h>
#ifndef WMINSTANTTITLE_H
#define WMINSTANTTITLE_H
#include <stdlib.h>
void InstantTitleHideDialog(ClientData *pClientData);
void InstantTitleShowDialog(ClientData *pClientData);
#endif
void *
__fix_realloc(void *p, size_t n)
{
return (p == 0 ? malloc(n) : realloc(p, n));
}

View file

@ -0,0 +1,86 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: snprintf.c /main/3 1996/06/11 17:14:27 cde-hal $ */
#include <sys/types.h>
#include "cdefs.h"
#include <compat.h>
#include <string.h>
#include <stdio.h>
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
int
#ifdef __STDC__
snprintf(char *str, size_t n, const char *fmt, ...)
#else
snprintf(str, n, fmt, va_alist)
char *str;
size_t n;
const char *fmt;
va_dcl
#endif
{
va_list ap;
#ifdef VSPRINTF_CHARSTAR
char *rp;
#else
int rval;
#endif
#ifdef __STDC__
va_start(ap, fmt);
#else
va_start(ap);
#endif
#ifdef VSPRINTF_CHARSTAR
rp = (char*)(size_t)vsnprintf(str, n, fmt, ap);
va_end(ap);
return (strlen(rp));
#else
rval = vsnprintf(str, n, fmt, ap);
va_end(ap);
return (rval);
#endif
}
#if 0
int
vsnprintf(str, n, fmt, ap)
char *str;
size_t n;
const char *fmt;
va_list ap;
{
#ifdef VSPRINTF_CHARSTAR
return (strlen((char*)(size_t)vsnprintf(str, fmt, ap)));
#else
return (vsnprintf(str, fmt, ap));
#endif
}
#endif

View file

@ -48,10 +48,9 @@
*/
#include "utility/debug.h"
#include "compression/code.h"
encoding_unit::encoding_unit(std::string* w, unsigned int f) :
encoding_unit::encoding_unit(ostring* w, unsigned int f) :
word(w), bits(0), freq(f), code(0), leaf_htr_node(NULL)
{
}
@ -61,7 +60,7 @@ encoding_unit::~encoding_unit()
delete word;
}
std::ostream& operator<<(std::ostream& out, encoding_unit& eu)
ostream& operator<<(ostream& out, encoding_unit& eu)
{
debug(out, *eu.word);
debug(out, eu.freq);

View file

@ -51,8 +51,7 @@
#ifndef _code_h
#define _code_h 1
#include <string>
#include "utility/ostring.h"
////////////////////////////////////////
//
////////////////////////////////////////
@ -62,17 +61,17 @@ class htr_node;
class encoding_unit
{
public:
std::string* word;
ostring* word;
int bits;
unsigned int freq;
unsigned int code;
htr_node* leaf_htr_node;
public:
encoding_unit(std::string* w, unsigned int freq);
encoding_unit(ostring* w, unsigned int freq);
~encoding_unit();
friend std::ostream& operator <<(std::ostream&, encoding_unit&);
friend ostream& operator <<(ostream&, encoding_unit&);
};

View file

@ -310,7 +310,7 @@ void huff::compress(const buffer& uncompressed, buffer& compressed)
void huff::decompress(buffer& compressed, buffer& uncompressed)
{
char* buf_base = uncompressed.get_base();
const char* str;
char* str;
int str_len;
char rem_bits;
@ -339,7 +339,7 @@ void huff::decompress(buffer& compressed, buffer& uncompressed)
//}
str_len = node_ptr -> eu -> word -> size();
str = node_ptr -> eu -> word -> c_str();
str = node_ptr -> eu -> word -> get();
if ( str_len == 1 ) {
@ -379,8 +379,8 @@ void huff::decompress(buffer& compressed, buffer& uncompressed)
uncompressed.set_content_sz(buf_base-uncompressed.get_base());
if ( rem_bits > 0 )
uncompressed.put( node_ptr -> eu -> word -> c_str(),
node_ptr -> eu -> word -> size()
uncompressed.put( node_ptr -> eu -> word -> get(),
node_ptr -> eu -> word -> size()
);
}
@ -422,7 +422,7 @@ io_status huff::cdrOut(buffer& buf)
word_sz = e_units[i] -> word -> size();
v_out_buf.put(char(word_sz));
v_out_buf.put(e_units[i] -> word -> c_str(), word_sz);
v_out_buf.put(e_units[i] -> word -> get(), word_sz);
v_out_buf.put(e_units[i] -> freq);
}

View file

@ -221,7 +221,7 @@ void trie::add(unsigned char* word, int sz, int fq)
encoding_unit* trie::add_to_alphabet(unsigned char* word, int sz, int fq)
{
extend_alphabet();
encoding_unit *x = new encoding_unit(new string((char*)word, sz), fq);
encoding_unit *x = new encoding_unit(new ostring((char*)word, sz), fq);
alphabet[alphabet_sz++] = x;
return x;
}
@ -240,7 +240,7 @@ cerr << "\n";
static trie_node_info* y = 0;
static char buf[1];
static string *z;
static ostring *z;
if ( root == 0 )
root = new trie_node(0);
@ -261,7 +261,7 @@ cerr << "\n";
y -> info.info_view.letter = j;
buf[0] = char(j);
z = new string(buf, 1);
z = new ostring(buf, 1);
y -> info.info_view.mark = 1;
extend_alphabet();
@ -292,7 +292,7 @@ void update_index(int ind, void* x)
void trie::_find_leaf(trie_node* z, int& j)
{
trie_node_info* x = 0;
string *y;
ostring *y;
for ( int i=0; i<LANG_ALPHABET_SZ; i++ ) {
#ifdef C_API
@ -322,7 +322,7 @@ encoding_unit** trie::get_alphabet(unsigned int& a_sz)
return alphabet;
}
string* trie::get_word(trie_node_info* leaf)
ostring* trie::get_word(trie_node_info* leaf)
{
static char buf[128];
buf[127] = 0;
@ -343,7 +343,7 @@ string* trie::get_word(trie_node_info* leaf)
}
//debug(cerr, buf+i);
return new string(buf+i, 127-i);
return new ostring(buf+i, 127-i);
}
Boolean trie::travers_to(char* str, int len,

View file

@ -130,7 +130,7 @@ protected:
protected:
void collect_freqs(trie_node* rt, int level);
string* get_word(trie_node_info* x);
ostring* get_word(trie_node_info* x);
void _find_leaf(trie_node* z, int& j);
void extend_alphabet();

View file

@ -53,6 +53,7 @@
#define _index_agent_h 1
#include "utility/funcs.h"
#include "utility/ostring.h"
#include "dynhash/data_t.h"
//**************************************************************

View file

@ -80,7 +80,7 @@ size_t btree_index::handler_to_inv_idx(const handler& query)
{
get_key_string(query);
data_t k(v_static_key.c_str(), v_static_key.size());
data_t k(v_static_key.get(), v_static_key.size());
if ( v_idx_agent_ptr -> member(k) == false )
throw(stringException("first_of_invlist(): key is not in btree"));

View file

@ -53,7 +53,7 @@
#define _btree_index_h 1
#include "index/dyn_index.h"
#include "btree/btree.h"
#include "btree/mmdb_btree.h"
class btree_index : public dyn_index
{

View file

@ -81,7 +81,7 @@ if ( v_static_key.get() )
MESSAGE(cerr, "************");
*/
return new data_t(v_static_key.c_str(), v_static_key.size());
return new data_t(v_static_key.get(), v_static_key.size());
}
Boolean

View file

@ -257,7 +257,7 @@ debug(cerr, k);
throw(stringException("hash table empty"));
}
i = v_tbl0 -> atoi(k.c_str(), k.size(), r, v_key_set_sz); // for halmphf
i = v_tbl0 -> atoi(k.get(), k.size(), r, v_key_set_sz); // for halmphf
if ( i < v_p1 ) {
@ -275,7 +275,7 @@ debug(cerr, k);
//i = v_tbl1 -> atoi(k, c_bit+r+1) + gv;
//debug(cerr, c_bit+r);
i = v_tbl1 -> atoi(k.c_str(), k.size(), c_bit+r+1, v_hash_tbl_sz) + gv; // for halmphf
i = v_tbl1 -> atoi(k.get(), k.size(), c_bit+r+1, v_hash_tbl_sz) + gv; // for halmphf
return i % v_hash_tbl_sz;
@ -422,7 +422,7 @@ fast_mphf::print_mapping(const char *key_file, int option)
//debug(cerr, option);
MESSAGE(cerr, "print_mapping()");
char str[LBUFSIZ];
char string[LBUFSIZ];
fstream in(key_file, ios::in);
if ( !in ) {
@ -432,23 +432,23 @@ fast_mphf::print_mapping(const char *key_file, int option)
char *hash_table = new char[v_hash_tbl_sz];
for (unsigned int i = 0; i < v_hash_tbl_sz; hash_table[i++] = 0 );
string lbuf; lbuf.reserve(LBUFSIZ);
ostring lbuf(LBUFSIZ);
while ( in.getline(str, LBUFSIZ, '\n') ) {
while ( in.getline(string, LBUFSIZ, '\n') ) {
// str[strlen(str)-1] = '\0';
// string[strlen(string)-1] = '\0';
//debug(cerr, str);
//debug(cerr, strlen(str));
//debug(cerr, string);
//debug(cerr, strlen(string));
lbuf.clear();
lbuf.assign(str, strlen(str));
lbuf.reset();
lbuf.set(string, strlen(string));
int hash = hashTo(lbuf) ;
if ( option == 1 ) {
cout << " string = " << str;
cout << " string = " << string;
cout << ", hash = " << hash << "\n";
}
@ -457,7 +457,7 @@ fast_mphf::print_mapping(const char *key_file, int option)
else
hash_table[hash] = 1;
in.getline(str, LBUFSIZ, '\n');
in.getline(string, LBUFSIZ, '\n');
}
MESSAGE(cerr, "print_mapping() done");

View file

@ -54,7 +54,7 @@
key_type* c_index::v_static_key_ptr;
#define v_static_key (*v_static_key_ptr)
#else
key_type c_index::v_static_key;
key_type c_index::v_static_key(LBUFSIZ);
#endif
void c_index::init_persistent_info(persistent_info* x)
@ -66,7 +66,6 @@ void c_index::init_persistent_info(persistent_info* x)
c_index::c_index(c_code_t c_cd) : composite(c_cd), v_inv_lists_hd(NULL)
{
v_cmp_selector = 0;
v_static_key.reserve(LBUFSIZ);
}
oid_list_handler* c_index::operator()(int ind)
@ -109,21 +108,27 @@ oid_t c_index::first_of_invlist(int ind)
Boolean c_index::get_key_string(const handler& t) const
{
ostringstream out;
int len;
((handler&)t) -> asciiOut(out);
v_static_key = out.str();
len = out.str().size();
v_static_key.set_size(len);
*((char *) memcpy(v_static_key.get(), out.str().c_str(), len) + len) = '\0';
return true;
}
Boolean c_index::get_key_string(const oid_t& t) const
{
v_static_key.clear();
ostringstream out(v_static_key.c_str());
v_static_key.reset();
int len;
ostringstream out(v_static_key.get());
t.asciiOut(out);
v_static_key = out.str();
len = out.str().size();
v_static_key.set_size(len);
*((char *) memcpy(v_static_key.get(), out.str().c_str(), len) + len) = '\0';
return true;
}

View file

@ -150,13 +150,13 @@ debug(cerr, (void*)(v_mphf->operator->()));
v_sz = (*v_mphf) -> keysetsize();
(*v_inv_lists_hd) -> expand_space(v_sz);
key_type key; key.reserve(LBUFSIZ);
key_type key(LBUFSIZ);
#ifdef DEBUG
int i = 0;
#endif
while (std::getline(in, key)) {
while ( in >> key ) {
oid_t key_id(c_code_t(0), 0);

View file

@ -62,7 +62,7 @@ debug(cerr, y -> v_name);
*/
return ( x -> v_name.compare(y -> v_name) < 0);
return ( x -> v_name.string_LS(y -> v_name) );
}
Boolean name_oid_eq(const void* o1, const void* o2)
@ -75,7 +75,7 @@ MESSAGE(cerr, "in name_oid_eq");
debug(cerr, x -> v_name);
debug(cerr, y -> v_name);
*/
return ( x -> v_name.compare(y -> v_name) == 0);
return ( x -> v_name.string_EQ(y -> v_name) );
}
Boolean oid_ls(const void* o1, const void* o2)
@ -145,14 +145,15 @@ void delete_name_oid_rec_f(const void* name_oid_ptr)
//
// ***************************************************
mark_t::mark_t(char* marks) : string(marks)
mark_t::mark_t(char* marks) : ostring(strlen(marks))
{
set(marks);
}
istream& operator >>(istream& in, mark_t& m)
{
char c ;
const char* ptr = m.c_str();
char* ptr = m.get();
Boolean read_marks = false;
while ( in && in.get(c) ) {
@ -174,7 +175,7 @@ istream& operator >>(istream& in, mark_t& m)
ostream& operator <<(ostream& out, mark_t& m)
{
out << m.c_str();
out << m.get();
return out ;
}

View file

@ -52,6 +52,7 @@
#define _misc_h
#include "object/root.h"
#include "utility/ostring.h"
#include "storage/abs_storage.h"
#include "object/handler.h"
@ -70,25 +71,25 @@ class name_oid_t
public:
name_oid_t(const char* nm, abs_storage* store = 0) : v_store(store)
{
v_name.assign(nm);
v_name.set(nm);
}
name_oid_t(const char* nm, const oid_t& id, abs_storage* store = 0) :
v_oid(id), v_store(store)
{
v_name.assign(nm);
v_name.set(nm);
};
~name_oid_t() {};
public:
string v_name;
ostring v_name;
oid_t v_oid;
abs_storage* v_store;
};
void delete_name_oid_rec_f(const void* name_oid_ptr);
class mark_t : private string
class mark_t : private ostring
{
public:
mark_t(char* marks = (char*)"\t\n ");

View file

@ -20,17 +20,14 @@
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: name_oid_t.h /main/3 1996/06/11 17:22:59 cde-hal $ */
class name_oid_t {
#ifndef _DT_SVC_PAM_H
#define _DT_SVC_PAM_H
public:
ostring name;
oid_t v_oid;
int _DtSvcPamAuthenticate(const char *service_name, const char *user,
const char *display_name, const char *user_passwd);
int _DtSvcPamOpenSession(const char *service_name, const char *user,
const char *display_name);
int _DtSvcPamCloseSession(const char *service_name, const char *user,
const char *display_name);
int _DtSvcPamSetcred(const char *service_name, const char *user,
const char *display_name);
#endif
name_oid_t(const char* nm, oid_t& id) : v_oid(id) {
name.set(nm);
};
};

View file

@ -52,6 +52,7 @@
#define _long_pstring_h 1
#include "object/pstring.h"
#include "utility/ostring.h"
#include "storage/page_storage.h"
#include "storage/chunks_index.h"

View file

@ -52,7 +52,7 @@
void oid_list::init_persistent_info(persistent_info* x)
{
string* u = list_ptr.p;
ostring* u = list_ptr.p;
root::init_persistent_info(x);
@ -62,7 +62,7 @@ void oid_list::init_persistent_info(persistent_info* x)
//debug(cerr, (void*)this);
//debug(cerr, my_oid());
const char* w = 0;
char* w = 0;
int v= 0;
//MESSAGE(cerr, "oid_list::init_persistent_info(), new object case");
@ -70,7 +70,7 @@ void oid_list::init_persistent_info(persistent_info* x)
//debug(cerr, (void*)list_ptr.p);
if (u) {
w = u -> c_str();
w = u -> get();
v = u -> size();
}
@ -132,7 +132,7 @@ void oid_list::init_data_member(int leng)
}
list_ptr.loc = 0; // to please purify
list_ptr.p = new string(ptr, char_leng);
list_ptr.p = new ostring(ptr, char_leng);
//MESSAGE(cerr, "oid_list::init_data_member(int leng)");
//debug(cerr, (void*)this);
@ -170,6 +170,8 @@ debug(cerr, int(list_ptr.loc));
debug(cerr, int(&list_ptr.loc));
*/
Boolean ok;
int extra_char_leng = extra_oids * OID_T_SZ;
if ( get_mode(PERSISTENT) == true ) {
@ -187,15 +189,18 @@ debug(cerr, int(&list_ptr.loc));
}
delete [] ptr;
ok = true;
} else {
list_ptr.p -> resize( extra_char_leng );
ok = list_ptr.p -> expand( extra_char_leng );
}
v_sz += extra_oids;
set_mode(UPDATE, true);
return true;
return ok;
}
@ -270,7 +275,7 @@ debug(cerr, int(list_ptr.p));
if ( list_ptr.p == 0 )
throw(stringException("zero list_ptr.p value"));
memcpy(z, list_ptr.p -> c_str() + offset, OID_T_SZ);
memcpy(z, list_ptr.p -> get() + offset, OID_T_SZ);
}
//MESSAGE(cerr, "oid_list::operator() done");
@ -358,7 +363,7 @@ oid_list::update_component(int index, const oid_t& new_oid)
if ( list_ptr.p == 0 )
throw(stringException("zero list_ptr.p value"));
list_ptr.p -> replace((index-1)*OID_T_SZ, OID_T_SZ, z);
list_ptr.p -> update(z, OID_T_SZ, (index-1)*OID_T_SZ);
}
//MESSAGE(cerr, "oid_list::update_component() done");
@ -430,8 +435,8 @@ io_status oid_list::asciiIn(istream& in)
} else {
delete list_ptr.p;
list_ptr.p = new string(0);
list_ptr.p -> assign(oid_array, v_sz);
list_ptr.p = new ostring(0);
list_ptr.p -> set(oid_array, v_sz);
}
delete [] oid_array;

View file

@ -51,6 +51,7 @@
#ifndef _oid_list_h
#define _oid_list_h 1
#include "utility/ostring.h"
#include "dstr/dlist.h"
#include "dstr/dlist_void_ptr_cell.h"
#include "object/oid.h"
@ -70,7 +71,7 @@ protected:
union {
mmdb_pos_t loc;
string* p;
ostring* p;
} list_ptr;
protected:

View file

@ -91,7 +91,7 @@ oid_t::oid_t(const char* source, Boolean ascii_format, Boolean swap_order)
memcpy((char*)&v_i_code, source, sizeof(v_i_code));
if ( swap_order == true )
ORDER_SWAP_I_CODE_T(v_i_code);
ORDER_SWAP_LONG(v_i_code);
} else {
istringstream in((char*)source);
@ -248,7 +248,7 @@ void oid_t::to_char_string(char* sink, Boolean swap_order) const
if ( swap_order == true ) {
i_code_t x = v_i_code;
ORDER_SWAP_I_CODE_T(x);
ORDER_SWAP_LONG(x);
memcpy(sink, (char*)&x, sizeof(x));
} else
memcpy(sink, (char*)&v_i_code, sizeof(v_i_code));

View file

@ -65,7 +65,6 @@ typedef unsigned short c_code_t;
typedef mmdb_pos_t i_code_t;
#define OID_T_SZ (sizeof(i_code_t))
#define ORDER_SWAP_I_CODE_T(x) ORDER_SWAP(i_code_t, x)
/*************************************
// class code root

View file

@ -164,7 +164,7 @@ handler* btree_index_desc::init_handler(object_dict& dict)
(*(btree_index_handler*)v_handler_ptr) ->
init_data_member(
(inv_lists_handler*)inv_handler,
form("%s/%s", dict.db_path(), get_agent_nm())
form("%s/%s", get_agent_nm(), dict.db_path())
);
(*(btree_index_handler*)v_handler_ptr) -> set_selector(position) ;

View file

@ -53,6 +53,7 @@
#define _object_dict 1
#include "dstr/bset.h"
#include "utility/ostring.h"
#include "object/handler.h"
#include "mgrs/template_mgr.h"

View file

@ -118,7 +118,7 @@ public:
};
void swap_order() {
ORDER_SWAP_MMDB_POS_T(fwd_ptr);
ORDER_SWAP_LONG(fwd_ptr);
ORDER_SWAP_UINT(header.int_view);
swapped = true;
};

View file

@ -4,7 +4,7 @@ noinst_LTLIBRARIES = libutility.la
libutility_la_CXXFLAGS = -DPORTABLE_DB -I..
libutility_la_SOURCES = funcs.C pm_random.C \
libutility_la_SOURCES = funcs.C ostring.C pm_random.C \
atoi_pearson.C xtime.C buffer.C \
atoi_larson.C atomic_lock.C rw_lock.C \
atoi_fast.C filter.C mmdb_exception.C \

View file

@ -98,7 +98,7 @@ union u_tag {
int atoi_fast::atoi(const key_type& k, int offset) const
{
const char* string = k.c_str();
char* string = k.get();
int l = k.size();
return atoi((const char*)string, l, offset, 0);
}

View file

@ -73,7 +73,7 @@ atoi_larson::atoi(const char* str, int sz, int, int rang) const
int
atoi_larson::atoi(const key_type& k, int) const
{
const char* string = k.c_str();
char* string = k.get();
int l = k.size();
unsigned int sum = 0;

View file

@ -52,7 +52,6 @@
#else
#include <values.h>
#endif
#include <string.h>
#include "key.h"
// Based on Larson's algorithm presented in CACM ???.

View file

@ -129,7 +129,7 @@ union u_tag {
int atoi_pearson::atoi(const key_type& k, int offset) const
{
const char* string = k.c_str();
char* string = k.get();
int l = k.size();
return atoi((const char*)string, l, offset, 0);
}

View file

@ -45,8 +45,8 @@
#ifndef _key_h
#define _key_h 1
#include <string>
#include "utility/ostring.h"
typedef std::string key_type;
typedef ostring key_type;
#endif

View file

@ -77,18 +77,48 @@
/* little endian to/from big endian swap macros. */
#define ORDER_SWAP(type, value) \
{ \
type tmp = value; \
int n = sizeof(type) - 1; \
for (int i = 0; i <= n; ++i) \
((uint8_t *)&value)[i] = ((uint8_t *)&tmp)[n - i]; \
#define ORDER_SWAP_LONG(x) \
{ \
long tmp_long = x; \
((unsigned char*)&x)[0] = ((unsigned char*)&tmp_long)[3]; \
((unsigned char*)&x)[1] = ((unsigned char*)&tmp_long)[2]; \
((unsigned char*)&x)[2] = ((unsigned char*)&tmp_long)[1]; \
((unsigned char*)&x)[3] = ((unsigned char*)&tmp_long)[0]; \
}
#define ORDER_SWAP_FLOAT(x) ORDER_SWAP(float, x)
#define ORDER_SWAP_LONG(x) ORDER_SWAP(long, x)
#define ORDER_SWAP_INT(x) ORDER_SWAP(int, x)
#define ORDER_SWAP_UINT(x) ORDER_SWAP(unsigned int, x)
#define ORDER_SWAP_USHORT(x) ORDER_SWAP(unsigned short, x)
#define ORDER_SWAP_MMDB_POS_T(x) ORDER_SWAP(mmdb_pos_t, x)
#define ORDER_SWAP_FLOAT(x) \
{ \
float tmp_float = x; \
((unsigned char*)&x)[0] = ((unsigned char*)&tmp_float)[3]; \
((unsigned char*)&x)[1] = ((unsigned char*)&tmp_float)[2]; \
((unsigned char*)&x)[2] = ((unsigned char*)&tmp_float)[1]; \
((unsigned char*)&x)[3] = ((unsigned char*)&tmp_float)[0]; \
}
#define ORDER_SWAP_INT(x) \
{ \
int tmp_uint = x; \
((unsigned char*)&x)[0] = ((unsigned char*)&tmp_uint)[3]; \
((unsigned char*)&x)[1] = ((unsigned char*)&tmp_uint)[2]; \
((unsigned char*)&x)[2] = ((unsigned char*)&tmp_uint)[1]; \
((unsigned char*)&x)[3] = ((unsigned char*)&tmp_uint)[0]; \
}
#define ORDER_SWAP_UINT(x) \
{ \
unsigned int tmp_uint = x; \
((unsigned char*)&x)[0] = ((unsigned char*)&tmp_uint)[3]; \
((unsigned char*)&x)[1] = ((unsigned char*)&tmp_uint)[2]; \
((unsigned char*)&x)[2] = ((unsigned char*)&tmp_uint)[1]; \
((unsigned char*)&x)[3] = ((unsigned char*)&tmp_uint)[0]; \
}
#define ORDER_SWAP_USHORT(x) \
{ \
unsigned short tmp_ushort = x; \
((unsigned char*)&x)[0] = ((unsigned char*)&tmp_ushort)[1]; \
((unsigned char*)&x)[1] = ((unsigned char*)&tmp_ushort)[0]; \
}
#endif

View file

@ -0,0 +1,284 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* $XConsortium: ostring.cc /main/3 1996/06/11 17:38:07 cde-hal $
*
* Copyright (c) 1992 HaL Computer Systems, Inc. All rights reserved.
* UNPUBLISHED -- rights reserved under the Copyright Laws of the United
* States. Use of a copyright notice is precautionary only and does not
* imply publication or disclosure.
*
* This software contains confidential information and trade secrets of HaL
* Computer Systems, Inc. Use, disclosure, or reproduction is prohibited
* without the prior express written permission of HaL Computer Systems, Inc.
*
* RESTRICTED RIGHTS LEGEND
* Use, duplication, or disclosure by the Government is subject to
* restrictions as set forth in subparagraph (c)(l)(ii) of the Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7013.
* HaL Computer Systems, Inc.
* 1315 Dell Avenue, Campbell, CA 95008
*
*/
#include "utility/ostring.h"
#ifdef C_API
char* ostring::input_buf = 0;
#else
char ostring::input_buf[LBUFSIZ];
#endif
ostring::ostring() : v_sz(0), v_allo_sz(1)
{
v_p = new char[1];
}
ostring::ostring(const int i) : v_sz(0), v_allo_sz(i+1)
{
v_p = new char[i+1];
}
ostring::ostring(char* x, const int i)
{
int w = i;
if ( w == -1 ) {
w = strlen(x);
}
v_sz = w;
v_allo_sz = w+1;
v_p = new char[w+1];
memcpy(v_p, x, w);
v_p[w] = 0;
}
ostring::ostring(const ostring& s) :
v_sz(s.v_sz), v_allo_sz(s.v_allo_sz)
{
v_p = new char[v_allo_sz];
memcpy(v_p, s.v_p, v_sz);
v_p[v_sz] = 0;
}
/*
ostring::~ostring()
{
delete v_p;
}
*/
Boolean ostring::set(const char* x, int l)
{
expand(l+1);
memcpy(v_p, x, l);
v_p[l] = 0;
v_sz = l;
return true;
}
/*
Boolean ostring::set(const char* x)
{
return set(x, strlen(x));
}
void ostring::reset()
{
v_sz = 0;
}
void ostring::set_size(const int s)
{
v_sz = s;
v_p[v_sz] = 0;
}
*/
/********************************************/
// set alloc_sz to at least new_alloc_sz bytes
/********************************************/
Boolean ostring::expand(const int new_alloc_sz, Boolean pre_zero)
{
if ( new_alloc_sz > v_allo_sz ) {
v_allo_sz = new_alloc_sz+1;
char* new_p = new char[v_allo_sz];
if ( pre_zero == true )
memset(new_p, char(0), v_allo_sz);
if ( v_p ) {
memcpy(new_p, v_p, v_sz);
delete [] v_p;
}
v_p = new_p;
}
return true;
}
char* ostring::acquire()
{
v_allo_sz = v_sz = 0;
char *x = v_p;
v_p = 0;
return x;
}
Boolean ostring::append(const char* x, int l)
{
expand(v_sz+l+1);
memcpy(v_p+v_sz, x, l);
v_sz += l;
v_p[v_sz] = 0;
return true;
}
Boolean ostring::update(const char* x, int l, int offset)
{
if ( offset + l > v_sz ) {
MESSAGE(cerr, "update(): char chunk too small");
throw(boundaryException(0, v_sz, offset+l));
}
memcpy(v_p+offset, x, l);
return true;
}
int ostring::substr(ostring& s)
{
if ( v_p == 0 || s.v_p == 0 )
return -1;
char* sub_p = strstr(v_p, s.v_p);
if ( sub_p == 0 )
return -1;
else
return (int)(sub_p - v_p);
}
/*
int ostring::size() const
{
return v_sz;
}
int ostring::alloc_size() const
{
return v_allo_sz;
}
*/
ostring& ostring::operator +(ostring& s)
{
int l1 = v_sz;
int l2 = s.v_sz;
ostring *new_ostring = new ostring(l1+l2);
int i;
for ( i = 0; i<l1; (*new_ostring).v_p[i] = s.v_p[i] ) i++;
for ( i = 0; i<l2; (*new_ostring).v_p[l1 + i] = s.v_p[i] ) i++;
return *new_ostring;
}
Boolean ostring::string_LS(ostring& y) const
{
char* x_str = this -> get() ;
char* y_str = y.get() ;
int x_sz = this -> size() ;
int y_sz = y.size() ;
if ( x_sz == y_sz ) {
if ( memcmp(x_str, y_str, x_sz ) < 0 )
return true;
else
return false;
} else {
int min = MIN(x_sz, y_sz);
for ( int i=0; i<min; i++ ) {
if ( x_str[i] < y_str[i] )
return true;
else
if ( x_str[i] > y_str[i] )
return false;
}
if ( x_sz < y_sz )
return true;
else
return false;
}
}
Boolean ostring::string_EQ(ostring& y) const
{
if ( this -> size() == y.size() &&
memcmp(this -> get(), y.get(), this -> size() ) == 0
)
return true;
else
return false;
}
ostream& operator <<(ostream& s, const ostring& o)
{
if ( o.v_p ) {
//s << o.v_sz << ":";
for ( int i=0; i<o.v_sz; i++ )
// if ( isprint(o.v_p[i]) )
s << o.v_p[i];
// else
// s << int(o.v_p[i]);
}
return s;
}
istream& operator >>(istream& s, ostring& o)
{
s.getline( o.input_buf, LBUFSIZ );
o.set(o.input_buf);
return s;
}
ostring* ostring::operator+= (ostring* )
{
return 0;
}
ostring* ostring::concate_with(...)
{
return 0 ;
}

View file

@ -0,0 +1,113 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* $XConsortium: ostring.h /main/3 1996/06/11 17:38:12 cde-hal $
*
* Copyright (c) 1992 HaL Computer Systems, Inc. All rights reserved.
* UNPUBLISHED -- rights reserved under the Copyright Laws of the United
* States. Use of a copyright notice is precautionary only and does not
* imply publication or disclosure.
*
* This software contains confidential information and trade secrets of HaL
* Computer Systems, Inc. Use, disclosure, or reproduction is prohibited
* without the prior express written permission of HaL Computer Systems, Inc.
*
* RESTRICTED RIGHTS LEGEND
* Use, duplication, or disclosure by the Government is subject to
* restrictions as set forth in subparagraph (c)(l)(ii) of the Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7013.
* HaL Computer Systems, Inc.
* 1315 Dell Avenue, Campbell, CA 95008
*
*/
#ifndef _ostring_h
#define _ostring_h 1
#include "utility/funcs.h"
class ostring {
public:
ostring();
ostring(const int chunk_size);
ostring(char* str, const int str_sz = -1); // -1 means take strlen(str)
ostring(const ostring&);
virtual ~ostring() { delete [] v_p; };
// length of the string
int size() const { return v_sz; };
// length of the allocated chunk
int alloc_size() const { return v_allo_sz; };
ostring& operator +(ostring&); // merge of two strings
int substr(ostring&); // substring matching
// set string to content x
Boolean set(const char* x) { return set(x, strlen(x)); };
Boolean set(const char* x, int i); // set string to content x with length i
Boolean append(const char* x, int l); // append a string x of length i
Boolean update(const char* x, int l, int offset); // update a substring x of length i at 'offset'. offset + l should be sz
//set alloc_sz to at least new_alloc_sz bytes
// pre_zero = true -> zero new space before copy old content over
Boolean expand(const int, Boolean pre_zero = false);
void reset() { v_sz = 0; };
void set_size(const int s) { v_sz = s; v_p[v_sz] = 0; };
char* get() const { return v_p; }; // get char pointer p
char* acquire() ; // return what is pointed at by p and reset
// alloc_sz, sz, and p to 0;
// append x to this and return this.
ostring* operator+= (ostring* x);
// concate all ostring arguments (ostring* 's) to this and return this.
ostring* concate_with(...);
Boolean string_LS(ostring&) const;
Boolean string_EQ(ostring&) const;
friend ostream& operator <<(ostream&, const ostring&);
friend istream& operator >>(istream&, ostring&);
protected:
char *v_p; // memory chunk pointer
int v_sz; // string size
int v_allo_sz; // allocated memory chunk size
#ifdef C_API
static char* input_buf;
friend void initialize_MMDB();
friend void quit_MMDB();
#else
static char input_buf[LBUFSIZ];
#endif
};
#endif

View file

@ -47,10 +47,8 @@
#define _types_h 1
#ifdef C_API
#include <stdint.h>
#include "utility/c_iostream.h"
#else
#include <cstdint>
#include <iostream>
using namespace std;
#endif
@ -62,7 +60,15 @@ typedef char Boolean;
typedef void* voidPtr;
typedef char* charPtr;
typedef intptr_t mmdb_pos_t;
typedef short s_int16;
typedef unsigned short u_int16;
typedef int s_int32;
typedef unsigned int u_int32;
typedef long s_long32;
typedef float s_float32;
enum io_status { done, fail };
@ -70,4 +76,14 @@ class root;
typedef Boolean (*cmp_func_ptr_t)(const void*, const void*);
typedef void (*app_func_ptr_t)(const void*);
typedef void (*print_func_ptr_t)(ostream&, const void*);
//enum Boolean { true, false };
#if !defined(__linux__) && !defined(CSRG_BASED)
typedef long mmdb_pos_t;
#else
typedef int mmdb_pos_t;
#endif
#endif

View file

@ -0,0 +1,17 @@
MAINTAINERCLEANFILES = Makefile.in
lib_LTLIBRARIES = libDtPamSvc.la
# the PamSvc.h header file is located in include/Dt/
libDtPamSvc_la_SOURCES = PamSvc.c ${top_srcdir}/include/Dt/PamSvc.h
libDtPamSvc_la_LIBADD = -lpam
# in order to try to keep lib versions the same across platforms, (2.1.0)
if BSD
libDtPamSvc_la_LDFLAGS = -version-info 2:1:0
else
libDtPamSvc_la_LDFLAGS = -version-info 3:0:1
endif

310
cde/lib/DtPamSvc/PamSvc.c Normal file
View file

@ -0,0 +1,310 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $TOG: pam_svc.c /main/5 1997/06/04 16:30:21 samborn $ */
/*******************************************************************************
**
** pam_svc.c 1.10 95/11/25
**
** Copyright 1993, 1994, 1995 Sun Microsystems, Inc. All rights reserved.
**
** This file contains procedures specific to use of
** PAM (Pluggable Authentication Module) security library.
**
*******************************************************************************/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
/*
* Header Files
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include <sys/param.h>
#include <security/pam_appl.h>
#include <utmpx.h>
#include <unistd.h>
#if defined(__linux__)
#include <grp.h>
#endif
#include <Dt/PamSvc.h>
/*
* Local function declarations
*/
static int login_conv(int num_msg, const struct pam_message **msg,
struct pam_response **response, void *appdata_ptr);
static char* create_devname(char* short_devname);
/*
* Local structures and variables
*/
static struct pam_conv pam_conv = {login_conv, NULL};
static char *saved_user_passwd;
static pam_handle_t *pamh = NULL;
/****************************************************************************
* PamInit
*
* Initialize or Update PAM datastructures.
*
****************************************************************************/
static int PamInit(char* prog_name,
char* user,
char* line_dev,
char* display_name)
{
int status=PAM_SUCCESS;
if (!pamh) {
/* Open PAM (Plugable Authentication module ) connection */
status = pam_start( prog_name, user, &pam_conv, &pamh );
if (status != PAM_SUCCESS) pamh = NULL;
} else {
if (prog_name) pam_set_item(pamh, PAM_SERVICE, prog_name);
if (user) pam_set_item(pamh, PAM_USER, user);
}
if (status == PAM_SUCCESS) {
if (line_dev) pam_set_item(pamh, PAM_TTY, line_dev);
if (display_name) pam_set_item(pamh, PAM_RHOST, display_name);
}
return(status);
}
/****************************************************************************
* _DtAuthentication
*
* Authenticate that user / password combination is legal for this system
*
****************************************************************************/
int _DtAuthentication ( char* prog_name,
char* display_name,
char* user_passwd,
char* user,
char* line )
{
int status;
char* line_str = line ? line : "NULL";
char* line_dev = create_devname(line_str);
if (!user_passwd)
/* Password challenge required for dtlogin authentication */
return(PAM_AUTH_ERR);
status = PamInit(prog_name, user, line_dev, display_name);
if (status == PAM_SUCCESS) {
saved_user_passwd = user_passwd;
status = pam_authenticate( pamh, 0 );
};
if (status != PAM_SUCCESS) {
if (pamh) {
pam_end(pamh, PAM_ABORT);
pamh=NULL;
}
}
return(status);
}
/****************************************************************************
* _DtAccounting
*
* Work related to open and close of user sessions
****************************************************************************/
int _DtAccounting( char* prog_name,
char* display_name,
char* entry_id,
char* user,
char* line,
pid_t pid,
int entry_type,
int exitcode )
{
int session_type, status;
char *line_str = line ? line : "NULL";
char *line_dev = create_devname(line_str);
/* Open PAM (Plugable Authentication module ) connection */
status = PamInit(prog_name, user, line_dev, display_name);
/* Session accounting */
if (status == PAM_SUCCESS) switch(entry_type) {
case DEAD_PROCESS:
status = pam_close_session(pamh, 0);
break;
case USER_PROCESS:
case LOGIN_PROCESS:
default:
status = pam_open_session(pamh, 0);
break;
}
free(line_dev);
return(status);
}
/****************************************************************************
* _DtSetCred
*
* Set Users login credentials: uid, gid, and group lists
****************************************************************************/
int _DtSetCred(char* prog_name, char* user, uid_t uid, gid_t gid)
{
int cred_type, status;
status = PamInit(prog_name, user, NULL, NULL);
/* Set users credentials */
if (status == PAM_SUCCESS && setgid(gid) == -1)
status = DT_BAD_GID;
if ((status == PAM_SUCCESS &&
!user) || (initgroups(user, gid) == -1))
status = DT_INITGROUP_FAIL;
if (status == PAM_SUCCESS)
status = pam_setcred(pamh, PAM_ESTABLISH_CRED);
if (status == PAM_SUCCESS && (setuid(uid) == -1))
status = DT_BAD_UID;
return(status);
}
/***************************************************************************
* create_devname
*
* A utility function. Takes short device name like "console" and returns
* a long device name like "/dev/console"
***************************************************************************/
static char* create_devname(char* short_devname)
{
char* long_devname;
if (short_devname == NULL)
short_devname = "";
long_devname = (char *) malloc (strlen(short_devname) + 5);
if (long_devname == NULL)
return(NULL);
strcpy(long_devname,"/dev/");
strcat(long_devname, short_devname);
return(long_devname);
}
/*****************************************************************************
* login_conv():
*
* This is a conv (conversation) function called from the PAM
* authentication scheme. It returns the user's password when requested by
* internal PAM authentication modules and also logs any internal PAM error
* messages.
*****************************************************************************/
static int login_conv(int num_msg, const struct pam_message **msg,
struct pam_response **response, void *appdata_ptr)
{
const struct pam_message *m;
struct pam_response *r;
char *temp;
int k;
#ifdef lint
conv_id = conv_id;
#endif
if (num_msg <= 0)
return (PAM_CONV_ERR);
*response = (struct pam_response*)
calloc(num_msg, sizeof (struct pam_response));
if (*response == NULL)
return (PAM_CONV_ERR);
(void) memset(*response, 0, sizeof (struct pam_response));
k = num_msg;
m = *msg;
r = *response;
while (k--) {
switch (m->msg_style) {
case PAM_PROMPT_ECHO_OFF:
if (saved_user_passwd != NULL) {
r->resp = (char *) malloc(strlen(saved_user_passwd)+1);
if (r->resp == NULL) {
/* __pam_free_resp(num_msg, *response); */
*response = NULL;
return (PAM_CONV_ERR);
}
(void) strcpy(r->resp, saved_user_passwd);
r->resp_retcode=0;
}
m++;
r++;
break;
case PAM_ERROR_MSG:
m++;
r++;
break;
case PAM_TEXT_INFO:
m++;
r++;
break;
default:
break;
}
}
return (PAM_SUCCESS);
}

View file

@ -41,9 +41,6 @@
*/
#include <stddef.h>
#include "boolpars.h"
void yyerror(char *);
int yylex(void);
%}
%union {

View file

@ -84,8 +84,8 @@ int dbn /* Database number */
char *orec; /* ptr to current owner record contents in cache */
char *mrec; /* ptr to current member record contents in cache */
char *nrec; /* ptr to next member record contents in cache */
DB_ADDR mdba = 0; /* db address of current member record */
DB_ADDR ndba = 0; /* db address of next member record */
DB_ADDR mdba = NULL; /* db address of current member record */
DB_ADDR ndba = NULL; /* db address of next member record */
INT ordering; /* set order control variable */
int stat, compare; /* status code & sort comparison result */
SET_ENTRY *set_ptr;

View file

@ -53,7 +53,7 @@
int
d_crread(
long field, /* Field constant */
void *data, /* Data area to contain field contents */
char *data, /* Data area to contain field contents */
int dbn /* database number */
)
{

View file

@ -53,7 +53,7 @@
int
d_crwrite(
long field, /* field constant */
void *data, /* data area to contain field contents */
char *data, /* data area to contain field contents */
int dbn /* database number */
)
{

View file

@ -57,7 +57,7 @@
int
d_fillnew(
int nrec, /* record number */
const void *recval, /* record value */
const char *recval, /* record value */
int dbn /* database number */
)
{

View file

@ -53,7 +53,7 @@
*/
int
d_recread(
void *rec, /* ptr to record area */
char *rec, /* ptr to record area */
int dbn
)
{

View file

@ -53,7 +53,7 @@
*/
int
d_recwrite(
const void *rec, /* ptr to record area */
const char *rec, /* ptr to record area */
int dbn
)
{

View file

@ -1,243 +0,0 @@
/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* Header Files
*/
#include <stdlib.h>
#include <string.h>
#include <security/pam_appl.h>
/*
* Local function declarations
*/
static int login_conv(int num_msg, const struct pam_message **msg,
struct pam_response **response, void *appdata_ptr);
/*
* Local structures and variables
*/
static struct pam_conv pam_conv = {login_conv, NULL};
static char *saved_user_passwd;
static pam_handle_t *pamh;
static int PamStart(const char *service_name, const char *user,
const char *display_name)
{
int status;
char *colon, *hostname;
if (pamh) {
if (service_name)
status = pam_set_item(pamh, PAM_SERVICE, service_name);
if (status != PAM_SUCCESS && user) pam_set_item(pamh, PAM_USER, user);
}
else {
status = pam_start(service_name, user, &pam_conv, &pamh);
}
if (status != PAM_SUCCESS) goto done;
if (!display_name) goto done;
if (display_name[0] == ':') {
status = pam_set_item(pamh, PAM_TTY, display_name);
goto done;
}
if (!(hostname = strdup(display_name))) {
status = PAM_BUF_ERR;
goto done;
}
if (colon = strrchr(hostname, ':')) *colon = '\0';
status = pam_set_item(pamh, PAM_RHOST, hostname);
free(hostname);
done:
if (status != PAM_SUCCESS && pamh && pam_end(pamh, status) == PAM_SUCCESS)
pamh = NULL;
return status;
}
/**
* @brief Authenticate that user / password combination is legal for this
* system.
*
* @param service_name
* @param user
* @param display_name
* @param user_passwd
*
* @return See pam_authenticate.
*/
int _DtSvcPamAuthenticate(const char *service_name, const char *user,
const char *display_name, const char *user_passwd)
{
int status;
if (!user_passwd) return PAM_AUTH_ERR;
if ((status = PamStart(service_name, user, display_name)) != PAM_SUCCESS)
return status;
saved_user_passwd = (char *) user_passwd;
return pam_authenticate(pamh, PAM_DISALLOW_NULL_AUTHTOK);
}
/**
* @brief Start PAM session management.
*
* @param service_name
* @param user
* @param display_name
*
* @return See pam_open_session.
*/
int _DtSvcPamOpenSession(const char *service_name, const char *user,
const char *display_name)
{
int status;
if ((status = PamStart(service_name, user, display_name)) != PAM_SUCCESS)
return status;
return pam_open_session(pamh, 0);
}
/**
* @brief Terminate PAM session management.
*
* @param service_name
* @param user
* @param display_name
*
* @return See pam_close_session.
*/
int _DtSvcPamCloseSession(const char *service_name, const char *user,
const char *display_name)
{
int status;
if ((status = PamStart(service_name, user, display_name)) != PAM_SUCCESS)
return status;
return pam_close_session(pamh, 0);
}
/**
* @brief Set Users login credentials.
*
* @param service_name
* @param user
* @param display_name
*
* @return See pam_setcred.
*/
int _DtSvcPamSetcred(const char *service_name, const char *user,
const char *display_name)
{
int status;
if ((status = PamStart(service_name, user, display_name)) != PAM_SUCCESS)
return status;
return pam_setcred(pamh, PAM_ESTABLISH_CRED);
}
/*****************************************************************************
* login_conv():
*
* This is a conv (conversation) function called from the PAM
* authentication scheme. It returns the user's password when requested by
* internal PAM authentication modules and also logs any internal PAM error
* messages.
*****************************************************************************/
static int login_conv(int num_msg, const struct pam_message **msg,
struct pam_response **response, void *appdata_ptr)
{
const struct pam_message *m;
struct pam_response *r;
char *temp;
int k;
#ifdef lint
conv_id = conv_id;
#endif
if (num_msg <= 0)
return (PAM_CONV_ERR);
*response = (struct pam_response*)
calloc(num_msg, sizeof (struct pam_response));
if (*response == NULL)
return (PAM_BUF_ERR);
k = num_msg;
m = *msg;
r = *response;
while (k--) {
switch (m->msg_style) {
case PAM_PROMPT_ECHO_OFF:
if (saved_user_passwd != NULL) {
r->resp = (char *) malloc(strlen(saved_user_passwd)+1);
if (r->resp == NULL) {
/* __pam_free_resp(num_msg, *response); */
*response = NULL;
return (PAM_BUF_ERR);
}
(void) strcpy(r->resp, saved_user_passwd);
r->resp_retcode=0;
}
m++;
r++;
break;
case PAM_ERROR_MSG:
m++;
r++;
break;
case PAM_TEXT_INFO:
m++;
r++;
break;
default:
break;
}
}
return (PAM_SUCCESS);
}

View file

@ -172,8 +172,3 @@ libDtSvc_la_SOURCES = DtCodelibs/buf.C \
DtUtil2/Utility.c \
DtUtil2/XlationSvc.c \
DtUtil2/XmWrap.c
if HAS_PAM_LIBRARY
libDtSvc_la_SOURCES += DtUtil2/SvcPam.c
libDtSvc_la_LIBADD = $(PAMLIB)
endif

View file

@ -699,6 +699,7 @@ static void
Resize(Widget w)
{
DtTermWidget tw = (DtTermWidget) w;
DtTermData td = tw->vt.td;
/* let our superclass (the Term Widget) perform the resize... */
tw->core.widget_class->core_class.superclass->core_class.resize(w);
@ -879,6 +880,7 @@ static void
Destroy(Widget w)
{
DtTermWidget tw = (DtTermWidget) w;
DtTermData td = tw->vt.td;
/* remove the DtTermData structure contents, followed by the structure...
*/

View file

@ -572,6 +572,7 @@ _DtTermActionEditKeyExecute(Widget w, XEvent *event, String *params,
long keyNumber;
char *ret;
int i;
DtTermData td = tw->vt.td;
if (*num_params < 1) {
return;

Some files were not shown because too many files have changed in this diff Show more