/*
 * tools/lib/vg_create_dir_and_group.c
 *
 * Copyright (C) 1997 - 2000  Heinz Mauelshagen, Sistina Software
 *
 * May 1997
 * January,December 1998
 * January,February 1999
 * January 2000
 * January,February 2001
 *
 *
 * This LVM library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This LVM library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this LVM library; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA
 *
 */

/*
 *
 * Changelog
 *
 *    11/01/1998 - added deletion of volume group special file directory
 *    13/12/1998 - corrected flow
 *    26/01/1999 - made volume group directory prefix a preprocessor option
 *    16/02/1999 - changed special generation to new scheme
 *    08/02/2000 - use debug_enter()/debug_leave()
 *    31/01/2001 - only create things if they don't already exist (drobbins)
 *    13/02/2001 - don't create device nodes if we're using devfs
 *
 */

#include <liblvm.h>

int vg_create_dir_and_group ( vg_t *vg) {
   int gid = 6; /* Linux */
   int ret = 0;
   struct group *grent = NULL;
   struct stat statbuf;
   char buffer[NAME_LEN];

   debug_enter ( "vg_create_dir_and_group -- CALLED\n");

   if ( vg == NULL || vg_check_name ( vg->vg_name) < 0) ret = -LVM_EPARAM;
   
   if (lvm_check_devfs())
       ret = 0;
   else {
      vg_remove_dir_and_group_and_nodes ( vg->vg_name);
      if ( ( ret = stat ( LVM_DIR_PREFIX, &statbuf)) == -1) {
         if ( errno == ENOENT) {
            if ( mkdir ( LVM_DIR_PREFIX, 0555) == -1) {
               ret = -LVM_EVG_CREATE_DIR_AND_GROUP_MKDIR;
               goto vg_create_dir_and_group_end;
            }
         } else {
            ret = -LVM_EVG_CREATE_DIR_AND_GROUP_MKDIR;
            goto vg_create_dir_and_group_end;
         }
         ret = 0;
      }

      memset ( buffer, 0, sizeof ( buffer));
      snprintf ( buffer, sizeof ( buffer) - 1,
                         LVM_DIR_PREFIX "%s", vg->vg_name);
      if ( ( ret = stat ( buffer, &statbuf)) == -1) {
         if ( errno == ENOENT) {
            if ( mkdir ( buffer, 0555) == -1) {
               ret = -LVM_EVG_CREATE_DIR_AND_GROUP_MKDIR;
               goto vg_create_dir_and_group_end;
            }
         } else {
            ret = -LVM_EVG_CREATE_DIR_AND_GROUP_MKDIR;
            goto vg_create_dir_and_group_end;
         }
         ret = 0;
      }

      if ( chmod ( buffer, 0555) == -1)
         ret = -LVM_EVG_CREATE_DIR_AND_GROUP_CHMOD_DIR;
      else {
         if ( ( grent = getgrnam ( "disk")) != NULL) gid = grent->gr_gid;
         strcat ( buffer, "/group");
         if ( ( ret = stat ( buffer, &statbuf)) == -1) {
            if ( errno == ENOENT) {
               if ( mknod ( buffer, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
                            ( LVM_CHAR_MAJOR << MINORBITS) +
                            vg->vg_number) == -1)
                  ret = -LVM_EVG_CREATE_DIR_AND_GROUP_MKNOD;
               else if ( chmod ( buffer, 0640) == -1) 
                  ret = -LVM_EVG_CREATE_DIR_AND_GROUP_CHMOD_GROUP;
               else if ( chown ( buffer, 0, gid) == -1)
                  ret = -LVM_EVG_CREATE_DIR_AND_GROUP_CHOWN_GROUP;
            }
            ret = 0;
         }
      }
   }

vg_create_dir_and_group_end:

   debug_leave ( "vg_create_dir_and_group -- LEAVING with ret: %d\n", ret);
   return ret;
}
