Subversion Repositories DevTools

Rev

Blame | Last modification | View Log | RSS feed

/***************************************************************************
* Module name   : dosify.c
* Module type   : CMDFILE source file
* Environment(s): n/a
*
* Description:
*
    Dosify --- convert PATH for DOS
*
* Version   Who      Date        Description
            APY      02/03/00    Created
            APY      14/03/00    Handle .. correctly
*
* $Source: /cvsroot/device/DEVL/UTILS/CMDFILE/dosify.c,v $            
* $Revision: 1.3 $ $Date: 2004/10/08 03:07:37 $ $State: Exp $ 
* $Author: ayoung $ $Locker:  $
*.........................................................................*/
/*
*     Include Files
*     ---------------
*/
#include <ctype.h>
#include <unistd.h>
#include "cmdfile.h"

#undef  CONVERTDOTS     /* Convert multiple '.' to '_' */

#ifndef isblank
#define isblank(c)      ((c) == ' ' || (c) == '\t')
#endif
static  const char *    file_to_dos(const char *filename, char *buf);

int
dosify(
    String_t *str, const char *s )
{
    char  name[ PATH_MAX ], buf[ PATH_MAX ];
    int   len;

    if (expected(s++, ',') > 0 &&
            (len = pathargument(s, name, PATH_MAX)) > 0)
    {
        const char *p;

        p = file_to_dos(name, buf);
        verbose( " dosify(%s) = %s", name, p );
        StringCat(str, p);
        return (1+len);
    }
    return (-1);
}


static const char *
file_to_dos(
    const char *filename, char *buf)
{
    const   char *fname;
    int     dots, dots8, i;
    char    *dp, *sep;

/* NULL and special characters */
    if (filename == NULL ||
            strpbrk(filename, "\"*+,;<=>?[]|") != 0)
        return (filename);
    dp = buf, fname = filename;

/* Skip drive */
    if (isalpha(fname[0]) && fname[1] == ':') 
    {
        *dp++ = toupper(fname[0]), *dp++ = ':';
        fname += 2;
    }

/* Convert each directory/fname slashs */
    while (*fname)
    {
    /* File or directory name */
        if ((sep = strchr(fname, '/')) == (char *)NULL)
            sep = strchr(fname, '\\');

    /* Handle .. */
        if (!strncmp(fname, "../", 3) || !strncmp(fname, "..\\", 3)) 
        {
            (void) strcpy(dp, "..\\");
            fname += 3;
            dp += 3;
            continue;
        }

    /* Count dots,
        *   Check what filenames which violate 8+3 constraints,
        *   like "config.h.in", or ".emacs"?
        */
        for (dots=dots8=0, i=0;; i++) 
        {
            if (fname[i] == '\0' || fname[i] == '/' || fname[i] == '\\')
                break;
            if (fname[i] == '.') {
#if !defined(CONVERTDOTS)
                if (dots && sep == NULL)
                    return (filename);      /* reject */
#endif
                if (i < 8)
                dots8++;
                dots++;                     /* '.' count */
            }
        }

    /* First, transform the name part */
        for (i=0; *fname != '\0' && i < 8; i++)
        {
            if (*fname == '.') 
            {
                dots--;
                if (dots8-- <= 1)
                    break;
#if !defined(CONVERTDOTS)
                if (i < 7)
                    *dp++ = '_';            /* convert to '_' */
#endif
                fname++;
            } else if (*fname == '/' || *fname == '\\')
                break;
            else 
            {
                *dp++ = tolower(*fname++);
            }
        }
    
    /* Now skip to the last dot */
         while (*fname != '\0') {
               if (*fname == '.') {
                  if (dots-- <= 1)          /* consume additional dots */
                     break;
               } else if (*fname == '/' || *fname == '\\')
                  break;
               fname++;
        }

    /* Extension */
        if (fname && *fname == '.') {
            *dp++ = *fname++;               /* append '.' */
            for (i = 0; *fname != '\0' && i < 3; ++i) 
            {
                if (*fname == '/' || *fname == '\\')
                    break;
                *dp++ = tolower(*fname++);
            }
        }

    /* Look for next dir/file, consuming addition characters */
        while (*fname) 
        {
            if (*fname == '\\' || *fname == '/') 
            {
                fname++;
                *dp++ = '\\';               /* convert to DOS */
                break;
            }
            fname++;
        }
    }
    *dp = 0;                                /* terminate name */
    return buf;
}