1 /***********************************************************************
2 This file is part of HA, a general purpose file archiver.
3 Copyright (C) 1995 Harri Hirvola
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 ************************************************************************
19 HA PC/bcc specific routines
20 ***********************************************************************/
21
22
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include <dir.h>
29 #include "ha.h"
30 #include "archive.h"
31 #include "error.h"
32
33 typedef struct {
34 unsigned char attr;
35 } Mdhd;
36
37 static Mdhd mdhd;
38 struct stat filestat;
39
40
sig_handler(int signo)41 static void sig_handler(int signo) {
42
43 error(1,ERR_INT,signo);
44 }
45
md_init(void)46 void md_init(void) {
47
48 signal(SIGINT,sig_handler);
49 }
50
md_strcase(char * s)51 char *md_strcase(char *s) {
52
53 int i;
54
55 for (i=0;s[i];++i) s[i]=tolower(s[i]);
56 return s;
57 }
58
md_arcname(char * name_req)59 char *md_arcname(char *name_req) {
60
61 char drive[MAXDRIVE],dir[MAXDIR],file[MAXFILE],ext[MAXEXT];
62 static char an[_MAX_PATH];
63
64 fnsplit(name_req,drive,dir,file,ext);
65 if (!strcmp(ext,"")) strcpy(ext,"HA");
66 fnmerge(an,drive,dir,file,ext);
67 return md_strcase(an);
68 }
69
md_gethdr(int len,int mode)70 void md_gethdr(int len, int mode) {
71
72 static int longest=0;
73 static unsigned char *buf=NULL;
74
75 if (len>longest) {
76 if (buf!=NULL) buf=realloc(buf,len);
77 else buf=malloc(len);
78 if (buf==NULL) error(1,ERR_MEM,"md_gethdr()");
79 longest=len;
80 }
81 read(arcfile,buf,len);
82 if (buf[0]==MSDOSMDH) mdhd.attr=buf[1];
83 else {
84 switch(mode) {
85 case M_DIR:
86 mdhd.attr=FA_DIREC;
87 break;
88 default:
89 mdhd.attr=FA_ARCH;
90 break;
91 }
92 }
93 }
94
md_puthdr(void)95 void md_puthdr(void) {
96
97 unsigned char buf[2];
98
99 buf[0]=MSDOSMDH;
100 buf[1]=mdhd.attr;
101 write(arcfile,buf,2);
102 }
103
samefile(char * f1,char * f2)104 static int samefile(char *f1, char *f2) {
105
106 S16B rv;
107
108 f1=_fullpath(NULL,f1,0);
109 f2=_fullpath(NULL,f2,0);
110 md_strcase(f1);
111 md_strcase(f2);
112 if (f1==NULL || f2==NULL) {
113 if (f1!=NULL) free(f1);
114 if (f2!=NULL) free(f2);
115 rv=0;
116 }
117 else {
118 if (strcmp(f1,f2)==0) rv=1;
119 else rv=0;
120 free(f1);
121 free(f2);
122 }
123 return rv;
124 }
125
md_filetype(char * path,char * name)126 int md_filetype(char *path, char *name) {
127
128 char *fullpath;
129
130 if (!strcmp(name,".") || !strcmp(name,"..")) return T_SKIP;
131 fullpath=md_pconcat(0,path,name);
132 if (stat(fullpath,&filestat)<0) {
133 error(0,ERR_STAT,fullpath);
134 free(fullpath);
135 return T_SKIP;
136 }
137 mdhd.attr=_chmod(fullpath,0);
138 if (samefile(arcname, fullpath)) {
139 free(fullpath);
140 return T_SKIP;
141 }
142 if (mdhd.attr&FA_DIREC) return T_DIR;
143 if (mdhd.attr&(FA_HIDDEN|FA_SYSTEM|FA_LABEL)) {
144 if (!special) return T_SKIP;
145 else return T_REGULAR;
146 }
147 return T_REGULAR;
148 }
149
150
md_newfile(void)151 int md_newfile(void) {
152
153 return 2;
154 }
155
md_setft(char * file,U32B time)156 void md_setft(char *file,U32B time) {
157
158 int fh;
159 struct ftime t;
160 struct time dt;
161 struct date dd;
162
163 fh=open(file,O_WRONLY);
164 unixtodos(time,&dd,&dt);
165 t.ft_min=dt.ti_min;
166 t.ft_hour=dt.ti_hour;
167 t.ft_tsec=dt.ti_sec>>1;
168 t.ft_year=dd.da_year-1980;
169 t.ft_day=dd.da_day;
170 t.ft_month=dd.da_mon;
171 setftime(fh,&t);
172 close(fh);
173 }
174
md_setfattrs(char * file)175 void md_setfattrs(char *file) {
176
177 if (useattr) _chmod(file,1,mdhd.attr);
178 }
179
md_systime(void)180 U32B md_systime(void) {
181
182 struct time dt;
183 struct date dd;
184
185 gettime(&dt);
186 getdate(&dd);
187 return dostounix(&dd,&dt);
188 }
189
190
md_listhdr(void)191 void md_listhdr(void) {
192
193 printf("\ndhsar ");
194 }
195
attrstring(unsigned attr)196 static char *attrstring(unsigned attr) {
197
198 static char as[6];
199
200 sprintf(as,"%c%c%c%c%c",
201 (attr&FA_DIREC)?'d':'-',
202 (attr&FA_HIDDEN)?'h':'-',
203 (attr&FA_SYSTEM)?'s':'-',
204 (attr&FA_ARCH)?'a':'-',
205 (attr&FA_RDONLY)?'r':'-');
206 return as;
207 }
208
md_listdat(void)209 void md_listdat(void) {
210
211 printf("\n %s",attrstring(mdhd.attr));
212 }
213
md_timestring(unsigned long t)214 char *md_timestring(unsigned long t) {
215
216 struct time dt;
217 struct date dd;
218 static char ts[22];
219
220 unixtodos(t,&dd,&dt);
221 sprintf(ts,"%04d-%02d-%02d %02d:%02d",dd.da_year,dd.da_mon,dd.da_day,
222 dt.ti_hour,dt.ti_min);
223 return ts;
224 }
225
md_truncfile(int fh,U32B len)226 void md_truncfile(int fh, U32B len) {
227
228 chsize(fh,len);
229 }
230
md_tohapath(char * mdpath)231 char *md_tohapath(char *mdpath) {
232
233 static char p[_MAX_PATH];
234 int i,j;
235
236 for (i=0;mdpath[i];++i) if (mdpath[i]!='.' && mdpath[i]!='\\') break;
237 while (i>0 && mdpath[i-1]=='.') --i;
238 if (i==0) skipemptypath=1;
239 else skipemptypath=0;
240 for (j=0;mdpath[i];++i) {
241 switch(mdpath[i]) {
242 case '\\' :
243 p[j++]=0xff;
244 break;
245 default :
246 p[j++]=mdpath[i];
247 break;
248 }
249 }
250 p[j]=0;
251 return md_strcase(p);
252 }
253
md_trunclast(char * s)254 static int md_trunclast(char *s) {
255
256 char *ptr,*optr,name[8],ext[3];
257 int i,olen,nlen,elen;
258
259 if ((ptr=strrchr(s,'\\'))==NULL) ptr=s;
260 else ++ptr;
261 optr=ptr;
262 olen=strlen(ptr);
263 if (*ptr=='.') *ptr='_';
264 for (i=0;i<8;++i,++ptr) {
265 if (!*ptr || *ptr=='.') break;
266 name[i]=*ptr;
267 }
268 nlen=i;
269 if (!*ptr || (ptr=strrchr(ptr,'.'))==NULL) {
270 if (olen>8) {
271 for (ptr=optr,i=0;i<nlen;++i) *ptr++=name[i];
272 *ptr=0;
273 }
274 return olen-nlen;
275 }
276 ++ptr;
277 for (i=0;i<3;++i,++ptr) {
278 if (!*ptr) break;
279 ext[i]=*ptr;
280 }
281 elen=i;
282 for (ptr=optr,i=0;i<nlen;++i) *ptr++=name[i];
283 *ptr++='.';
284 for (i=0;i<elen;++i) *ptr++=ext[i];
285 *ptr=0;
286 return olen-nlen-elen-1;
287 }
288
md_tomdpath(char * hapath)289 char *md_tomdpath(char *hapath) {
290
291 static char p[_MAX_PATH];
292 int i,j;
293
294 for (i=j=0;hapath[i];++i) {
295 switch(hapath[i]) {
296 case 0xff :
297 p[j]=0;
298 j-=md_trunclast(p);
299 p[j++]='\\';
300 break;
301 default :
302 p[j++]=hapath[i];
303 break;
304 }
305 }
306 p[j]=0;
307 j-=md_trunclast(p);
308 p[j]=0;
309 return p;
310 }
311
md_strippath(char * mdfullpath)312 char *md_strippath(char *mdfullpath) {
313
314 char drive[MAXDRIVE],dir[MAXDIR],file[MAXFILE],ext[MAXEXT];
315 static char path[MAXDRIVE+MAXDIR];
316
317 fnsplit(mdfullpath,drive,dir,file,ext);
318 fnmerge(path,drive,dir,"","");
319 return path;
320 }
321
md_stripname(char * mdfullpath)322 char *md_stripname(char *mdfullpath) {
323
324 char drive[MAXDRIVE],dir[MAXDIR],file[MAXFILE],ext[MAXEXT];
325 static char name[MAXFILE+MAXEXT];
326
327 fnsplit(mdfullpath,drive,dir,file,ext);
328 fnmerge(name,"","",file,ext);
329 return name;
330 }
331
md_pconcat(int delim,char * head,char * tail)332 char *md_pconcat(int delim, char *head, char *tail) {
333
334 char *newpath;
335 int headlen,delim1;
336
337 delim1=0;
338 if ((headlen=strlen(head))!=0) {
339 if (head[headlen-1]!='\\' && head[headlen-1]!=':') delim1=1;
340 }
341 if ((newpath=malloc(headlen+strlen(tail)+delim+delim1+1))==NULL)
342 error(1,ERR_MEM,"md_pconcat()");
343 if (headlen!=0) strcpy(newpath,head);
344 if (delim1) newpath[headlen]='\\';
345 strcpy(newpath+headlen+delim1,tail);
346 if (delim) strcpy(newpath+strlen(newpath),"\\");
347 return newpath;
348 }
349
md_mkspecial(char * ofname,unsigned sdlen,unsigned char * sdata)350 int md_mkspecial(char *ofname,unsigned sdlen,unsigned char *sdata) {
351
352 error(0,ERR_HOW,ofname);
353 return 0;
354 }
355
md_namecmp(char * pat,char * cmp)356 int md_namecmp(char *pat, char *cmp) {
357
358 for (;*pat;++pat) {
359 switch(*pat) {
360 case '?' :
361 if (*cmp!='.' && *cmp) ++cmp;
362 break;
363 case '*' :
364 while (*cmp!='.' && *cmp) ++cmp;
365 break;
366 case '.' :
367 if (*cmp=='.') {
368 cmp=strrchr(cmp,'.');
369 ++cmp;
370 }
371 else if (*cmp) return 0;
372 else {
373 do ++pat; while (*pat=='?');
374 if (*pat==0 || *pat=='*') {
375 while (*pat) ++pat;
376 }
377 --pat;
378 }
379 break;
380 default :
381 if (*cmp!=*pat) return 0;
382 ++cmp;
383 break;
384 }
385 }
386 if (*cmp==0) return 1;
387 else return 0;
388 }
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404