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