(root)/
man-db-2.12.0/
libdb/
db_delete.c
       1  /*
       2   * db_delete.c: dbdelete(), database delete routine.
       3   *
       4   * Copyright (C) 1994, 1995 Graeme W. Wilford. (Wilf.)
       5   * Copyright (C) 2001, 2002 Colin Watson.
       6   *
       7   * This library is free software; you can redistribute it and/or
       8   * modify it under the terms of the GNU Library General Public
       9   * License as published by the Free Software Foundation; either
      10   * version 2 of the License, or (at your option) any later version.
      11   *
      12   * This library is distributed in the hope that it will be useful,
      13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15   * Library General Public License for more details.
      16   *
      17   * You should have received a copy of the GNU Library General Public
      18   * License along with this library; if not, write to the Free Software
      19   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
      20   *
      21   * Mon Aug  8 20:35:30 BST 1994  Wilf. (G.Wilford@ee.surrey.ac.uk)
      22   */
      23  
      24  #ifdef HAVE_CONFIG_H
      25  #include "config.h"
      26  #endif /* HAVE_CONFIG_H */
      27  
      28  #include <stdio.h>
      29  #include <string.h>
      30  #include <stdlib.h>
      31  #include <unistd.h>
      32  
      33  #include "error.h"
      34  #include "gl_list.h"
      35  #include "xalloc.h"
      36  
      37  #include "gettext.h"
      38  #define _(String) gettext (String)
      39  
      40  #include "manconfig.h"
      41  
      42  #include "appendstr.h"
      43  #include "debug.h"
      44  #include "filenames.h"
      45  #include "glcontainers.h"
      46  
      47  #include "mydbm.h"
      48  #include "db_storage.h"
      49  
      50  /* Delete an entry for a page.
      51     Again, 3 possibilities:
      52  
      53     1) page is singular reference, just delete it :)
      54     2) page has 2+ companions. Delete page and alter multi entry to not
      55        point to it anymore.
      56     3) page has 1 companion. Could do as (2), but we'd waste an entry in
      57        the db. Should delete page, extract friend and reinsert as singular,
      58        overwriting the old multi entry.
      59  */
      60  
      61  #define NO_ENTRY	1;
      62  
      63  int dbdelete (MYDBM_FILE dbf, const char *name, struct mandata *info)
      64  {
      65  	datum key, cont;
      66  
      67  	memset (&key, 0, sizeof key);
      68  	memset (&cont, 0, sizeof cont);
      69  
      70  	/* get entry for info */
      71  
      72  	debug ("Attempting delete of %s(%s) entry.\n", name, info->ext);
      73  
      74  	MYDBM_SET (key, name_to_key (name));
      75  	cont = MYDBM_FETCH (dbf, key);
      76  
      77  	if (!MYDBM_DPTR (cont)) {			/* 0 entries */
      78  		MYDBM_FREE_DPTR (key);
      79  		return NO_ENTRY;
      80  	} else if (*MYDBM_DPTR (cont) != '\t') {	/* 1 entry */
      81  		MYDBM_DELETE (dbf, key);
      82  		MYDBM_FREE_DPTR (cont);
      83  	} else {					/* 2+ entries */
      84  		gl_list_t refs;
      85  		struct name_ext this_ref, *ref;
      86  		size_t this_index;
      87  		char *multi_content = NULL;
      88  		datum multi_key;
      89  
      90  		/* Extract all of the extensions associated with
      91  		   this key */
      92  
      93  		refs = list_extensions (MYDBM_DPTR (cont) + 1);
      94  
      95  		this_ref.name = name;
      96  		this_ref.ext = info->ext;
      97  		this_index = gl_list_indexof (refs, &this_ref);
      98  
      99  		if (this_index == (size_t) -1) {
     100  			gl_list_free (refs);
     101  			MYDBM_FREE_DPTR (cont);
     102  			MYDBM_FREE_DPTR (key);
     103  			return NO_ENTRY;
     104  		}
     105  
     106  		multi_key = make_multi_key (name, info->ext);
     107  		if (!MYDBM_EXISTS (dbf, multi_key)) {
     108  			error (0, 0,
     109  			       _( "multi key %s does not exist"),
     110  			       MYDBM_DPTR (multi_key));
     111  			gripe_corrupt_data (dbf);
     112  		}
     113  		MYDBM_DELETE (dbf, multi_key);
     114  		MYDBM_FREE_DPTR (multi_key);
     115  		gl_list_remove_at (refs, this_index);
     116  
     117  		/* If all manual pages with this name have been deleted,
     118  		   we'll have to remove the key too. */
     119  
     120  		if (!gl_list_size (refs)) {
     121  			gl_list_free (refs);
     122  			MYDBM_FREE_DPTR (cont);
     123  			MYDBM_DELETE (dbf, key);
     124  			MYDBM_FREE_DPTR (key);
     125  			return 0;
     126  		}
     127  
     128  		/* create our new multi content */
     129  		multi_content = xstrdup ("");
     130  		GL_LIST_FOREACH (refs, ref)
     131  			multi_content = appendstr (multi_content,
     132  						   "\t", ref->name,
     133  						   "\t", ref->ext,
     134  						   (void *) 0);
     135  
     136  		MYDBM_FREE_DPTR (cont);
     137  		MYDBM_SET (cont, multi_content);
     138  		if (MYDBM_REPLACE (dbf, key, cont))
     139  			gripe_replace_key (dbf, MYDBM_DPTR (key));
     140  
     141  		gl_list_free (refs);
     142  	}
     143  
     144  	MYDBM_FREE_DPTR (key);
     145  	return 0;
     146  }