/*
** This software is Copyright (c) 1989, 1990, 1991 by Kent Landfield.
**
** Permission is hereby granted to copy, distribute or otherwise 
** use any part of this package as long as you do not try to make 
** money from it or pretend that you wrote it.  This copyright 
** notice must be maintained in any copy made.
**
*/

#if !defined(lint) && !defined(SABER)
static char SID[] = "@(#)makedir.c	2.2 5/9/91";
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include "rkive.h"

extern char *progname;

extern int verbose;
extern int test;

extern FILE *errfp;
extern FILE *logfp;

int makedir(dirpath, mode, owner_id, group_id)
    char *dirpath;
    int mode;
    int owner_id;
    int group_id;
{
    int strlen();
    int chown();

#ifndef MKDIR
# ifndef USE_SYSMKDIR

    char *strcat();
    char *strncpy();
    char *strcpy();
    int access();
    int mknod();
    int link();
    int unlink();

    register i;
    register slen = 0;

    char parent[MAXNAMLEN];

# else /* USE_SYSMKDIR */

    int chmod();

# endif /* USE_SYSMKDIR */

    char crnt_dir[MAXNAMLEN];

#else /* MKDIR */

    int mkdir();
    int svmask;          /* Old umask value */

#endif /* MKDIR */
    
    if ((strlen(dirpath) == 0) || (dirpath[0] == '\0')) {
        (void) fprintf(errfp,"%s: cannot make %s\n", progname,dirpath);
        return(-1);
    }

    if (verbose) {
        (void) fprintf(logfp,"making\t<%s>\n",dirpath);
        if (test) 
            return(0);
    }

#ifdef MKDIR

    /*
    ** mkdir function supplied in system library.
    */

    svmask = umask(0);

    if (mkdir(dirpath,mode) != 0)
        return(-1);

    (void) umask(svmask);
    (void) chown(dirpath, owner_id, group_id);

#else
# ifdef USE_SYSMKDIR

    /* 
    ** Use the system mkdir executable.. why?
    */

    /* build up command */

    (void) sprintf(crnt_dir, "/bin/mkdir %s", dirpath);

    if (system(crnt_dir) != 0)
        return(-1);

    (void) chmod(dirpath, mode);
    (void) chown(dirpath, owner_id, group_id);

# else

    /*
    ** Builtin mkdir function in use ...
    **
    ** Save the parent path
    */

    i = 0;
    parent[0] = '\0';

    while (dirpath[i]) {
        if (dirpath[i] == '/')
            slen = i + 1;
        ++i;
    }

    if (slen)    /* Is there a parent string to save ? */
        (void) strncpy(parent, dirpath, slen);

    (void) strcpy(parent+slen, ".");

    /* Does the parent directory exist and is it writable ? */

    if (access(parent, 02)) {
        (void) fprintf(errfp,"%s: cannot access %s\n", progname,parent);
        return(-1);
    }

    /* make the actual directory file */

    if ((mknod(dirpath, S_IFDIR | mode, 0)) < 0) {
        (void)fprintf(errfp,"%s: can't make directory %s\n",progname,dirpath);
        return(-1);
    }

    (void) chown(dirpath, owner_id, group_id);

    /* need to create the "." directory entry */

    (void) strcpy(crnt_dir, dirpath);
    (void) strcat(crnt_dir, "/.");

    if ((link(dirpath, crnt_dir)) < 0) {
        /* 
        ** Could not link the  directory to it's "." entry.
        ** Clean up and return.
        */
        (void) unlink(dirpath);
        (void) fprintf(errfp, "%s: cannot link [%s]\n", progname,crnt_dir);
        return(-1);
    }

    /* need to create the "." directory entry */

    (void) strcat(crnt_dir, ".");

    if ((link(parent, crnt_dir)) < 0) {
        /* 
        ** Could not link the parent directory to the ".." entry.
        ** Clean up and return.
        */
        crnt_dir[strlen(crnt_dir)] = '\0';
        (void) unlink(crnt_dir);
        (void) unlink(dirpath);
        (void) fprintf(errfp, "%s: cannot link [%s]\n",progname,crnt_dir);
        return(-1);
    }
#endif /* USE_SYSMKDIR */
#endif /* MKDIR */
    return(0); 
}
