curia man page on DragonFly

Man page or keyword search:  
man Server   44335 pages
apropos Keyword Search (all sections)
Output format
DragonFly logo
[printable version]

CURIA(3)		    Quick Database Manager		      CURIA(3)

NAME
       Curia - the extended API of QDBM

SYNOPSIS
       #include <depot.h>
       #include <curia.h>
       #include <stdlib.h>

       CURIA *cropen(const char *name, int omode, int bnum, int dnum);

       int crclose(CURIA *curia);

       int  crput(CURIA	 *curia, const char *kbuf, int ksiz, const char *vbuf,
       int vsiz, int dmode);

       int crout(CURIA *curia, const char *kbuf, int ksiz);

       char *crget(CURIA *curia, const char *kbuf, int ksiz,  int  start,  int
       max, int *sp);

       int  crgetwb(CURIA  *curia,  const char *kbuf, int ksiz, int start, int
       max, char *vbuf);

       int crvsiz(CURIA *curia, const char *kbuf, int ksiz);

       int criterinit(CURIA *curia);

       char *criternext(CURIA *curia, int *sp);

       int crsetalign(CURIA *curia, int align);

       int crsetfbpsiz(CURIA *curia, int size);

       int crsync(CURIA *curia);

       int croptimize(CURIA *curia, int bnum);

       char *crname(CURIA *curia);

       int crfsiz(CURIA *curia);

       double crfsizd(CURIA *curia);

       int crbnum(CURIA *curia);

       int crbusenum(CURIA *curia);

       int crrnum(CURIA *curia);

       int crwritable(CURIA *curia);

       int crfatalerror(CURIA *curia);

       int crinode(CURIA *curia);

       time_t crmtime(CURIA *curia);

       int crremove(const char *name);

       int crrepair(const char *name);

       int crexportdb(CURIA *curia, const char *name);

       int crimportdb(CURIA *curia, const char *name);

       char *crsnaffle(const char *name, const char *kbuf, int ksiz, int *sp);

       int crputlob(CURIA *curia, const	 char  *kbuf,  int  ksiz,  const  char
       *vbuf, int vsiz, int dmode);

       int croutlob(CURIA *curia, const char *kbuf, int ksiz);

       char *crgetlob(CURIA *curia, const char *kbuf, int ksiz, int start, int
       max, int *sp);

       int crgetlobfd(CURIA *curia, const char *kbuf, int ksiz);

       int crvsizlob(CURIA *curia, const char *kbuf, int ksiz);

       int crrnumlob(CURIA *curia);

DESCRIPTION
       Curia is the extended API of QDBM.  It provides routines	 for  managing
       multiple database files in a directory.	Restrictions of some file sys‐
       tems that the size of each file is limited are escaped  by  dividing  a
       database file into two or more.	If the database files deploy on multi‐
       ple devices, the scalability is improved.

       Although Depot creates a database with a file  name,  Curia  creates  a
       database	 with  a  directory name.  A database file named as `depot' is
       placed in the specified directory.  Although it keeps the attribute  of
       the  database,  it does not keep the entities of the records.  Besides,
       sub directories are created by the number of division of the  database,
       named  with 4 digits.  The database files are placed in the subdirecto‐
       ries.  The entities of the records are stored  in  the  database	 file.
       For  example,  in  the case that a database directory named as `casket'
       and the number of division is 3,	 `casket/depot',  `casket/0001/depot',
       `casket/0002/depot'  and	 `casket/0003/depot'  are  created.   No error
       occurs even if the namesake directory exists when creating a  database.
       So,  if	sub directories exists and some devices are mounted on the sub
       directories, the database files deploy on the multiple devices.	It  is
       possible	 for  the  database  files  to deploy on multiple file servers
       using NFS and so on.

       Curia features managing large  objects.	 Although  usual  records  are
       stored  in  some database files, records of large objects are stored in
       individual files.  Because the files of large objects are  deployed  in
       different  directories  named with the hash values, the access speed is
       part-way robust although it is slower than the speed of usual  records.
       Large  and not often accessed data should be secluded as large objects.
       By doing this, the access speed of  usual  records  is  improved.   The
       directory  hierarchies  of  large  objects  are placed in the directory
       named as `lob' in the sub directories of the database.  Because the key
       spaces  of  the	usual records and the large objects are different, the
       operations keep out of each other.

       In order to use Curia, you  should  include  `depot.h',	`curia.h'  and
       `stdlib.h'  in  the  source  files.  Usually, the following description
       will be near the beginning of a source file.

	      #include <depot.h>
	      #include <curia.h>
	      #include <stdlib.h>

       A pointer to `CURIA' is used as a database handle.   It	is  like  that
       some  file  I/O routines of `stdio.h' use a pointer to `FILE'.  A data‐
       base handle is opened  with  the	 function  `cropen'  and  closed  with
       `crclose'.   You should not refer directly to any member of the handle.
       If a fatal error occurs in a database, any access method via the handle
       except  `crclose'  will	not  work and return error status.  Although a
       process is allowed to use multiple database handles at the  same	 time,
       handles of the same database directory should not be used.

       Curia  also assign the external variable `dpecode' with the error code.
       The function `dperrmsg' is used in order to  get	 the  message  of  the
       error code.

       The function `cropen' is used in order to get a database handle.

       CURIA *cropen(const char *name, int omode, int bnum, int dnum);
	      `name'  specifies	 the  name  of	a database directory.  `omode'
	      specifies	 the  connection  mode:	 `CR_OWRITER'  as  a   writer,
	      `CR_OREADER' as a reader.	 If the mode is `CR_OWRITER', the fol‐
	      lowing may be added by bitwise or: `CR_OCREAT', which  means  it
	      creates a new database if not exist, `CR_OTRUNC', which means it
	      creates a new  database  regardless  if  one  exists.   Both  of
	      `CR_OREADER'  and	 `CR_OWRITER'  can  be added to by bitwise or:
	      `CR_ONOLCK', which means it opens a database  directory  without
	      file  locking,  or `CR_OLCKNB', which means locking is performed
	      without blocking.	 `CR_OCREAT' can be added to  by  bitwise  or:
	      `CR_OSPARSE',  which  means  it creates database files as sparse
	      files.  `bnum' specifies the number of elements of  each	bucket
	      array.   If  it  is not more than 0, the default value is speci‐
	      fied.  The size of each bucket array is determined on  creating,
	      and  can	not be changed except for by optimization of the data‐
	      base.  Suggested size of each bucket array is about from 0.5  to
	      4 times of the number of all records to store.  `dnum' specifies
	      the number of division of the database.  If it is not more  than
	      0,  the  default value is specified.  The number of division can
	      not be changed from the initial value.  The max number of	 divi‐
	      sion  is 512.  The return value is the database handle or `NULL'
	      if it is not successful.	 While	connecting  as	a  writer,  an
	      exclusive lock is invoked to the database directory.  While con‐
	      necting as a reader, a shared lock is invoked  to	 the  database
	      directory.   The	thread	blocks until the lock is achieved.  If
	      `CR_ONOLCK' is used, the application is responsible  for	exclu‐
	      sion control.

       The function `crclose' is used in order to close a database handle.

       int crclose(CURIA *curia);
	      `curia'  specifies a database handle.  If successful, the return
	      value is true, else, it is  false.   Because  the	 region	 of  a
	      closed handle is released, it becomes impossible to use the han‐
	      dle.  Updating a database is assured to be written when the han‐
	      dle  is closed.  If a writer opens a database but does not close
	      it appropriately, the database will be broken.

       The function `crput' is used in order to store a record.

       int crput(CURIA *curia, const char *kbuf, int ksiz, const  char	*vbuf,
       int vsiz, int dmode);
	      `curia'  specifies  a  database  handle  connected  as a writer.
	      `kbuf' specifies the pointer to the region  of  a	 key.	`ksiz'
	      specifies the size of the region of the key.  If it is negative,
	      the size is assigned with `strlen(kbuf)'.	 `vbuf' specifies  the
	      pointer  to the region of a value.  `vsiz' specifies the size of
	      the region of the	 value.	  If  it  is  negative,	 the  size  is
	      assigned	with  `strlen(vbuf)'.  `dmode' specifies behavior when
	      the key overlaps, by the	following  values:  `CR_DOVER',	 which
	      means   the   specified	value  overwrites  the	existing  one,
	      `CR_DKEEP', which means the existing value is  kept,  `CR_DCAT',
	      which  means  the	 specified value is concatenated at the end of
	      the existing value.  If successful, the return  value  is	 true,
	      else, it is false.

       The function `crout' is used in order to delete a record.

       int crout(CURIA *curia, const char *kbuf, int ksiz);
	      `curia'  specifies  a  database  handle  connected  as a writer.
	      `kbuf' specifies the pointer to the region  of  a	 key.	`ksiz'
	      specifies the size of the region of the key.  If it is negative,
	      the size is assigned with `strlen(kbuf)'.	  If  successful,  the
	      return value is true, else, it is false.	false is returned when
	      no record corresponds to the specified key.

       The function `crget' is used in order to retrieve a record.

       char *crget(CURIA *curia, const char *kbuf, int ksiz,  int  start,  int
       max, int *sp);
	      `curia'  specifies  a  database  handle.	 `kbuf'	 specifies the
	      pointer to the region of a key.  `ksiz' specifies	 the  size  of
	      the  region of the key.  If it is negative, the size is assigned
	      with `strlen(kbuf)'.  `start' specifies the  offset  address  of
	      the  beginning  of  the  region  of the value to be read.	 `max'
	      specifies the max size to be read.  If it is negative, the  size
	      to  read is unlimited.  `sp' specifies the pointer to a variable
	      to which the size of the region of the return value is assigned.
	      If  it  is  `NULL',  it  is not used.  If successful, the return
	      value is the pointer to the region of the value  of  the	corre‐
	      sponding record, else, it is `NULL'.  `NULL' is returned when no
	      record corresponds to the specified key or the size of the value
	      of  the  corresponding  record is less than `start'.  Because an
	      additional zero code is appended at the end of the region of the
	      return  value,  the  return  value can be treated as a character
	      string.  Because the region of the  return  value	 is  allocated
	      with  the	 `malloc'  call, it should be released with the `free'
	      call if it is no longer in use.

       The function `crgetwb' is used in order to retrieve a record and	 write
       the value into a buffer.

       int  crgetwb(CURIA  *curia,  const char *kbuf, int ksiz, int start, int
       max, char *vbuf);
	      `curia' specifies	 a  database  handle.	`kbuf'	specifies  the
	      pointer  to  the	region of a key.  `ksiz' specifies the size of
	      the region of the key.  If it is negative, the size is  assigned
	      with  `strlen(kbuf)'.   `start'  specifies the offset address of
	      the beginning of the region of the  value	 to  be	 read.	 `max'
	      specifies the max size to be read.  It shuld be equal to or less
	      than the size of	the  writing  buffer.	`vbuf'	specifies  the
	      pointer  to  a  buffer into which the value of the corresponding
	      record is written.  If successful, the return value is the  size
	      of  the  written	data,  else, it is -1.	-1 is returned when no
	      record corresponds to the specified key or the size of the value
	      of  the corresponding record is less than `start'.  Note that no
	      additional zero code is appended at the end of the region of the
	      writing buffer.

       The  function `crvsiz' is used in order to get the size of the value of
       a record.

       int crvsiz(CURIA *curia, const char *kbuf, int ksiz);
	      `curia' specifies	 a  database  handle.	`kbuf'	specifies  the
	      pointer  to  the	region of a key.  `ksiz' specifies the size of
	      the region of the key.  If it is negative, the size is  assigned
	      with  `strlen(kbuf)'.   If  successful,  the return value is the
	      size of the value of the corresponding record, else, it  is  -1.
	      Because  this  function does not read the entity of a record, it
	      is faster than `crget'.

       The function `criterinit' is used in order to initialize	 the  iterator
       of a database handle.

       int criterinit(CURIA *curia);
	      `curia'  specifies a database handle.  If successful, the return
	      value is true, else, it is false.	 The iterator is used in order
	      to access the key of every record stored in a database.

       The  function  `criternext' is used in order to get the next key of the
       iterator.

       char *criternext(CURIA *curia, int *sp);
	      `curia' specifies a database handle.  `sp' specifies the pointer
	      to  a  variable  to  which  the size of the region of the return
	      value is assigned.  If it is `NULL', it is not  used.   If  suc‐
	      cessful,	the  return  value is the pointer to the region of the
	      next key, else, it is `NULL'.  `NULL' is returned when no record
	      is  to  be  get out of the iterator.  Because an additional zero
	      code is appended at the end of the region of the	return	value,
	      the  return value can be treated as a character string.  Because
	      the region of the return value is allocated  with	 the  `malloc'
	      call,  it	 should	 be  released with the `free' call if it is no
	      longer in use.  It is possible to access every record by	itera‐
	      tion  of	calling	 this function.	 However, it is not assured if
	      updating the database is occurred while the iteration.  Besides,
	      the order of this traversal access method is arbitrary, so it is
	      not assured that the order of storing matches  the  one  of  the
	      traversal access.

       The  function `crsetalign' is used in order to set alignment of a data‐
       base handle.

       int crsetalign(CURIA *curia, int align);
	      `curia' specifies a  database  handle  connected	as  a  writer.
	      `align'  specifies  the  size  of alignment.  If successful, the
	      return value is true, else, it is false.	If alignment is set to
	      a	 database,  the	 efficiency of overwriting values is improved.
	      The size of alignment is suggested to be	average	 size  of  the
	      values  of  the records to be stored.  If alignment is positive,
	      padding whose size  is  multiple	number	of  the	 alignment  is
	      placed.	If  alignment  is negative, as `vsiz' is the size of a
	      value, the size of padding is calculated with  `(vsiz  /	pow(2,
	      abs(align)  - 1))'.  Because alignment setting is not saved in a
	      database, you should specify alignment every opening a database.

       The function `crsetfbpsiz' is used in order to set the size of the free
       block pool of a database handle.

       int crsetfbpsiz(CURIA *curia, int size);
	      `curia'  specifies  a  database  handle  connected  as a writer.
	      `size' specifies the size of the free block pool of a  database.
	      If successful, the return value is true, else, it is false.  The
	      default size of the free block pool  is  16.   If	 the  size  is
	      greater,	the space efficiency of overwriting values is improved
	      with the time efficiency sacrificed.

       The function `crsync' is used in order to synchronize updating contents
       with the files and the devices.

       int crsync(CURIA *curia);
	      `curia'  specifies  a database handle connected as a writer.  If
	      successful, the return value is true, else, it is	 false.	  This
	      function is useful when another process uses the connected data‐
	      base directory.

       The function `croptimize' is used in order to optimize a database.

       int croptimize(CURIA *curia, int bnum);
	      `curia' specifies a  database  handle  connected	as  a  writer.
	      `bnum'  specifies	 the  number  of  the  elements of each bucket
	      array.  If it is not more than 0, the default  value  is	speci‐
	      fied.  In an alternating succession of deleting and storing with
	      overwrite or concatenate, dispensable regions accumulate.	  This
	      function is useful to do away with them.

       The function `crname' is used in order to get the name of a database.

       char *crname(CURIA *curia);
	      `curia'  specifies a database handle.  If successful, the return
	      value is the pointer to the region of the name of the  database,
	      else,  it	 is `NULL'.  Because the region of the return value is
	      allocated with the `malloc' call, it should be released with the
	      `free' call if it is no longer in use.

       The  function  `crfsiz' is used in order to get the total size of data‐
       base files.

       int crfsiz(CURIA *curia);
	      `curia' specifies a database handle.  If successful, the	return
	      value  is	 the total size of the database files, else, it is -1.
	      If the total size is more than 2GB, the return value overflows.

       The function `crfsizd' is used in order to get the total size of	 data‐
       base files as double-precision floating-point number.

       double crfsizd(CURIA *curia);
	      `curia'  specifies a database handle.  If successful, the return
	      value is the total size of the database files, else, it is -1.0.

       The function `crbnum' is used in order to get the total number  of  the
       elements of each bucket array.

       int crbnum(CURIA *curia);
	      `curia'  specifies a database handle.  If successful, the return
	      value is the total number of the elements of each bucket	array,
	      else, it is -1.

       The  function  `crbusenum'  is used in order to get the total number of
       the used elements of each bucket array.

       int crbusenum(CURIA *curia);
	      `curia' specifies a database handle.  If successful, the	return
	      value  is	 the  total number of the used elements of each bucket
	      array, else, it is -1.  This function is inefficient because  it
	      accesses all elements of each bucket array.

       The function `crrnum' is used in order to get the number of the records
       stored in a database.

       int crrnum(CURIA *curia);
	      `curia' specifies a database handle.  If successful, the	return
	      value is the number of the records stored in the database, else,
	      it is -1.

       The function `crwritable' is used in order to check whether a  database
       handle is a writer or not.

       int crwritable(CURIA *curia);
	      `curia'  specifies  a database handle.  The return value is true
	      if the handle is a writer, false if not.

       The function `crfatalerror' is used in order to check whether  a	 data‐
       base has a fatal error or not.

       int crfatalerror(CURIA *curia);
	      `curia'  specifies  a database handle.  The return value is true
	      if the database has a fatal error, false if not.

       The function `crinode' is used in order to get the inode	 number	 of  a
       database directory.

       int crinode(CURIA *curia);
	      `curia'  specifies  a  database handle.  The return value is the
	      inode number of the database directory.

       The function `crmtime' is used in order to get the last	modified  time
       of a database.

       time_t crmtime(CURIA *curia);
	      `curia'  specifies  a  database handle.  The return value is the
	      last modified time of the database.

       The function `crremove' is used in order to remove  a  database	direc‐
       tory.

       int crremove(const char *name);
	      `name'  specifies the name of a database directory.  If success‐
	      ful, the return value is true, else, it is false.

       The function `crrepair' is used in order to repair  a  broken  database
       directory.

       int crrepair(const char *name);
	      `name'  specifies the name of a database directory.  If success‐
	      ful, the return value is true, else, it is false.	 There	is  no
	      guarantee that all records in a repaired database directory cor‐
	      respond to the original or expected state.

       The function `crexportdb' is used in  order  to	dump  all  records  as
       endian independent data.

       int crexportdb(CURIA *curia, const char *name);
	      `curia'  specifies a database handle.  `name' specifies the name
	      of an output directory.  If  successful,	the  return  value  is
	      true, else, it is false.	Note that large objects are ignored.

       The  function  `crimportdb'  is	used in order to load all records from
       endian independent data.

       int crimportdb(CURIA *curia, const char *name);
	      `curia' specifies a database handle connected as a writer.   The
	      database of the handle must be empty.  `name' specifies the name
	      of an input directory.  If successful, the return value is true,
	      else, it is false.  Note that large objects are ignored.

       The function `crsnaffle' is used in order to retrieve a record directly
       from a database directory.

       char *crsnaffle(const char *name, const char *kbuf, int ksiz, int *sp);
	      `name' specifies the name of a database directory.  `kbuf' spec‐
	      ifies  the pointer to the region of a key.  `ksiz' specifies the
	      size of the region of the key.  If it is negative, the  size  is
	      assigned	with  `strlen(kbuf)'.  `sp' specifies the pointer to a
	      variable to which the size of the region of the return value  is
	      assigned.	  If it is `NULL', it is not used.  If successful, the
	      return value is the pointer to the region of the	value  of  the
	      corresponding  record,  else,  it is `NULL'.  `NULL' is returned
	      when no record corresponds to the	 specified  key.   Because  an
	      additional zero code is appended at the end of the region of the
	      return value, the return value can be  treated  as  a  character
	      string.	Because	 the  region  of the return value is allocated
	      with the `malloc' call, it should be released  with  the	`free'
	      call  if	it is no longer in use.	 Although this function can be
	      used even while the database  directory  is  locked  by  another
	      process, it is not assured that recent updated is reflected.

       The function `crputlob' is used in order to store a large object.

       int  crputlob(CURIA  *curia,  const  char  *kbuf,  int ksiz, const char
       *vbuf, int vsiz, int dmode);
	      `curia' specifies a  database  handle  connected	as  a  writer.
	      `kbuf'  specifies	 the  pointer  to the region of a key.	`ksiz'
	      specifies the size of the region of the key.  If it is negative,
	      the  size is assigned with `strlen(kbuf)'.  `vbuf' specifies the
	      pointer to the region of a value.	 `vsiz' specifies the size  of
	      the  region  of  the  value.   If	 it  is	 negative, the size is
	      assigned with `strlen(vbuf)'.  `dmode' specifies	behavior  when
	      the  key	overlaps,  by  the following values: `CR_DOVER', which
	      means  the  specified  value  overwrites	 the   existing	  one,
	      `CR_DKEEP',  which  means the existing value is kept, `CR_DCAT',
	      which means the specified value is concatenated at  the  end  of
	      the  existing  value.   If successful, the return value is true,
	      else, it is false.

       The function `croutlob' is used in order to delete a large object.

       int croutlob(CURIA *curia, const char *kbuf, int ksiz);
	      `curia' specifies a  database  handle  connected	as  a  writer.
	      `kbuf'  specifies	 the  pointer  to the region of a key.	`ksiz'
	      specifies the size of the region of the key.  If it is negative,
	      the  size	 is  assigned with `strlen(kbuf)'.  If successful, the
	      return value is true, else, it is false.	false is returned when
	      no large object corresponds to the specified key.

       The function `crgetlob' is used in order to retrieve a large object.

       char *crgetlob(CURIA *curia, const char *kbuf, int ksiz, int start, int
       max, int *sp);
	      `curia' specifies	 a  database  handle.	`kbuf'	specifies  the
	      pointer  to  the	region of a key.  `ksiz' specifies the size of
	      the region of the key.  If it is negative, the size is  assigned
	      with  `strlen(kbuf)'.   `start'  specifies the offset address of
	      the beginning of the region of the  value	 to  be	 read.	 `max'
	      specifies	 the max size to be read.  If it is negative, the size
	      to read is unlimited.  `sp' specifies the pointer to a  variable
	      to which the size of the region of the return value is assigned.
	      If it is `NULL', it is not  used.	  If  successful,  the	return
	      value  is	 the  pointer to the region of the value of the corre‐
	      sponding large object, else, it is `NULL'.  `NULL'  is  returned
	      when  no	large  object  corresponds to the specified key or the
	      size of the value of the corresponding large object is less than
	      `start'.	Because an additional zero code is appended at the end
	      of the region of the return  value,  the	return	value  can  be
	      treated as a character string.  Because the region of the return
	      value is allocated with the `malloc' call, it should be released
	      with the `free' call if it is no longer in use.

       The  function  `crgetlobfd' is used in order to get the file descriptor
       of a large object.

       int crgetlobfd(CURIA *curia, const char *kbuf, int ksiz);
	      `curia' specifies	 a  database  handle.	`kbuf'	specifies  the
	      pointer  to  the	region of a key.  `ksiz' specifies the size of
	      the region of the key.  If it is negative, the size is  assigned
	      with  `strlen(kbuf)'.   If  successful,  the return value is the
	      file descriptor of the corresponding large object, else,	it  is
	      -1.   -1	is  returned  when  no large object corresponds to the
	      specified key.  The returned file descriptor is opened with  the
	      `open' call.  If the database handle was opened as a writer, the
	      descriptor is  writable  (O_RDWR),  else,	 it  is	 not  writable
	      (O_RDONLY).   The	 descriptor  should be closed with the `close'
	      call if it is no longer in use.

       The function `crvsizlob' is used in order to get the size of the	 value
       of a large object.

       int crvsizlob(CURIA *curia, const char *kbuf, int ksiz);
	      `curia'  specifies  a  database  handle.	 `kbuf'	 specifies the
	      pointer to the region of a key.  `ksiz' specifies	 the  size  of
	      the  region of the key.  If it is negative, the size is assigned
	      with `strlen(kbuf)'.  If successful, the	return	value  is  the
	      size of the value of the corresponding large object, else, it is
	      -1.  Because this function does not read the entity of  a	 large
	      object, it is faster than `crgetlob'.

       The  function  `crrnumlob'  is  used  in order to get the number of the
       large objects stored in a database.

       int crrnumlob(CURIA *curia);
	      `curia' specifies a database handle.  If successful, the	return
	      value is the number of the large objects stored in the database,
	      else, it is -1.

       If QDBM was built  with	POSIX  thread  enabled,	 the  global  variable
       `dpecode'  is  treated  as thread specific data, and functions of Curia
       are reentrant.  In that case, they are thread-safe as long as a	handle
       is  not	accessed  by  threads at the same time, on the assumption that
       `errno', `malloc', and so on are thread-safe.

SEE ALSO
       qdbm(3), depot(3), relic(3), hovel(3),  cabin(3),  villa(3),  odeum(3),
       ndbm(3), gdbm(3)

Man Page			  2004-04-22			      CURIA(3)
[top]

List of man pages available for DragonFly

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net