root/trunk/txlib/txmpath.c

Revision 1, 10.9 kB (checked in by jvw, 3 years ago)

Initial check-in for TxWin? version 1.02 sources

Line 
1//
2//                     TxWin, Textmode Windowing Library
3//
4//   Original code Copyright (c) 1995-2005 Fsys Software and Jan van Wijk
5//
6// ==========================================================================
7//
8// This file contains Original Code and/or Modifications of Original Code as
9// defined in and that are subject to the GNU Lesser General Public License.
10// You may not use this file except in compliance with the License.
11// BY USING THIS FILE YOU AGREE TO ALL TERMS AND CONDITIONS OF THE LICENSE.
12// A copy of the License is provided with the Original Code and Modifications,
13// and is also available at http://www.dfsee.com/txwin/lgpl.htm
14//
15// This library is free software; you can redistribute it and/or modify
16// it under the terms of the GNU Lesser General Public License as published
17// by the Free Software Foundation; either version 2.1 of the License,
18// or (at your option) any later version.
19//
20// This library is distributed in the hope that it will be useful,
21// but WITHOUT ANY WARRANTY; without even the implied warranty of
22// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23// See the GNU Lesser General Public License for more details.
24//
25// You should have received a copy of the GNU Lesser General Public License
26// along with this library; (lgpl.htm) if not, write to the Free Software
27// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28//
29// Questions on TxWin licensing can be directed to: txwin@fsys.nl
30//
31// ==========================================================================
32//
33// TxLib filesystem functions, make std and 8.3 paths
34//
35
36#include <txlib.h>                              // TxLib interface
37
38#include <sys/stat.h>                           // for low level stuff
39
40
41/*****************************************************************************/
42// Create path in a recursive fashion
43/*****************************************************************************/
44ULONG TxMakePath                                // RET   result
45(
46   char               *filename                 // IN    relative/absolute path
47)
48{
49   ULONG               rc = NO_ERROR;           // return value
50   #if defined (WIN32)
51      char            *p = NULL;
52      ULONG            ulAttr;
53   #elif defined (DOS32)
54      char            *p = NULL;
55      unsigned         usAttr;                  // attributes (dos.h)
56   #elif defined (LINUX)
57      //- to be refined
58   #else
59      char            *p = NULL;
60      FILESTATUS3      fstat;
61   #endif
62
63   ENTER();
64
65   #if defined (WIN32)
66      ulAttr = GetFileAttributes(filename);
67      if (ulAttr != TXINVALID)
68      {
69         if ((ulAttr & FILE_ATTRIBUTE_DIRECTORY) == 0)
70         {
71            TxPrint("\nCannot create directory, a file '%s' exists  ", filename);
72            rc = ERROR_FILE_EXISTS;             // file with same name exists
73         }
74      }
75      else                                      // not existing
76      {
77         rc = NO_ERROR;
78         if (strcmp(filename+1, ":"))           // no bare drive specification
79         {
80            if ((p = TxStripBaseName(filename)) != NULL) // last component
81            {
82               rc = TxMakePath(filename);
83               *(--p) = FS_PATH_SEP;            // join last part again
84            }
85            if (rc == NO_ERROR)
86            {
87               if (!CreateDirectory(filename, NULL)) // New, no security
88               {
89                  rc = TX_ERROR;
90               }
91            }
92         }
93      }
94   #elif defined (DOS32)
95      rc = (ULONG) _dos_getfileattr(filename, &usAttr);
96      TRACES(("get attr, RC %lu, attr %hx on: '%s'\n", rc, usAttr, filename));
97      if (rc == NO_ERROR)
98      {
99         if ((usAttr & _A_SUBDIR) == 0)         // it is an existing file
100         {
101            TxPrint("\nCannot create directory, a file '%s' exists  ", filename);
102            rc = ERROR_FILE_EXISTS;             // file with same name exists
103         }
104      }
105      else                                      // not existing
106      {
107         rc = NO_ERROR;
108         if (strcmp(filename+1, ":"))           // no bare drive specification
109         {
110            if ((p = TxStripBaseName(filename)) != NULL) // find last component
111            {
112               rc = TxMakePath(filename);
113               *(--p) = FS_PATH_SEP;            // join last part again
114            }
115            if (rc == NO_ERROR)
116            {
117               if (mkdir( filename) != 0)
118               {
119                  rc = TX_ERROR;
120               }
121            }
122         }
123      }
124   #elif defined (LINUX)
125      //- to be refined
126   #else
127      rc = DosQPathInfo(filename,               // Path string
128                        FIL_STANDARD,           // Path data required
129                        &fstat,                 // Path data buffer
130                        sizeof(fstat));         // Path data buffer size
131      TRACES(("DosQPathInfo, RC %lu on: '%s'\n", rc, filename));
132      if (rc == NO_ERROR)
133      {
134         if ((fstat.attrFile & FILE_DIRECTORY) == 0)
135         {
136            TxPrint("\nCannot create directory, a file '%s' exists  ", filename);
137            rc = ERROR_FILE_EXISTS;             // file with same name exists
138         }
139      }
140      else
141      {
142         rc = NO_ERROR;
143         if (strcmp(filename+1, ":"))           // no bare drive specification
144         {
145            if ((p = TxStripBaseName(filename)) != NULL) // find last component
146            {
147               rc = TxMakePath(filename);
148               *(--p) = FS_PATH_SEP;            // join last part again
149            }
150            if (rc == NO_ERROR)
151            {
152               rc = DosMkDir(filename, NULL);   // Create New, without EA's
153            }
154         }
155      }
156   #endif
157   RETURN (rc);
158}                                               // end 'TxMakePath'
159/*---------------------------------------------------------------------------*/
160
161
162/*****************************************************************************/
163// Make an 8-dot-3 compatible copy of supplied path/filename string (no spaces)
164/*****************************************************************************/
165ULONG TxMake8dot3                               // RET   length converted name
166(
167   char               *filename,                // IN    relative/absolute path
168   char               *fname8d3                 // OUT   8dot3 compatible
169)
170{
171   ULONG               rc = 0;                  // return value
172   char               *= filename;           // ptr in source name
173   char               *= fname8d3;           // ptr in converted name
174   ULONG               cs = 0;                  // checksum for segment
175   ULONG               i  = 0;                  // length converted part
176
177   ENTER();
178
179   TRACES(("filename : '%s'\n", filename));
180   do
181   {
182      if ((*p == '\\') || (*p == '/') ||        // end of any segment
183          (*p == ':')  || (*p == 0))
184      {
185         if (*p == ':')                         // end of drive part
186         {
187            cs = 0;                             // no cs on drive part
188         }
189         else if ((cs != 0) && (i > 8))         // add cs to converted ?
190         {                                      // . plus 3 upcase hex digits
191            cs = ((cs ^ (cs >> 24)) &0xfff);    // XOR and shuffle a bit
192            sprintf( d, ".%3.3lX", cs);
193            d += strlen(d);                     // advance to end of string
194         }
195         *d++ = *p;                             // copy character, convert space
196         i    = 0;                              // reset count on next segment
197         cs   = 0;                              // reset checksum
198      }
199      else                                      // other characters
200      {
201         if (i < 8)
202         {
203            if (*p == '.')                      // dot in dir/file name
204            {
205               if (strcspn( p+1, "\\/") <= 3)   // will be valid if total
206               {                                // stays 12 or less (8+1+3)
207                  *d = '.';                     // so keep the original dot
208                  i  = 4;                       // avoid conversion on next 3
209               }
210               else                             // translate to '_' because
211               {                                // .XXX will be added for cs
212                  *d = '_';
213                  i++;
214               }
215            }
216            else
217            {
218               *d = *p;                         // copy character
219               i++;
220            }
221            d++;                                // advance counter & dest
222         }
223         else                                   // conversion will happen
224         {
225            if ((i == 8) && (*p == '.'))        // dot in dir/file name
226            {
227               if (strcspn( p+1, "\\/") <= 3)   // will be valid if total
228               {                                // stays 12 or less (8+1+3)
229                  *d++ = '.';                   // so keep the original dot
230                  i    = 4;                     // avoid conversion on next 3
231               }
232               else                             // translate to '_' because
233               {                                // .XXX will be added for cs
234                  *(d-3) = *(d-2);              // shift last 2 chars back
235                  *(d-2) = *(d-1);
236                  if (*p == '.')
237                  {
238                     *(d-1) = '_';
239                  }
240                  else
241                  {
242                     *(d-1) = *p;
243                  }
244
245                  i++;
246                  rc = 1;                       // signal conversion made
247               }
248            }
249            else
250            {
251               *(d-3) = *(d-2);                 // shift last 2 chars back
252               *(d-2) = *(d-1);
253               if (*p == '.')
254               {
255                  *(d-1) = '_';
256               }
257               else
258               {
259                  *(d-1) = *p;
260               }
261
262               i++;
263               rc = 1;                          // signal conversion made
264            }
265         }
266         cs *= 2;                               // multiply by 2
267         cs += *p;                              // add char to checksum
268      }
269      if (*p != 0)
270      {
271         p++;
272      }
273   } while ((*p != 0) || (i >= 8));             // until end and cs added
274   *d = 0;                                      // always terminated
275
276   TxRepl( fname8d3, ' ', '_');                 // translate spaces
277   if (rc != 0)                                 // conversion made ?
278   {
279      rc = strlen( fname8d3);
280   }
281   TRACES(("fname out: '%s'\n", fname8d3));
282   RETURN (rc);
283}                                               // end 'TxMake8dot3'
284/*---------------------------------------------------------------------------*/
Note: See TracBrowser for help on using the browser.