#include <ctype.h> #include <string.h> #include <memory.h> #include <sys/types.h> #include <sys/time.h> #include <dos.h> static long timer = 0L,timeout; /* * Timer with a resolution of up to one millisecond (depends on hardware * capabilities). */ long milliseconds(timer) long *timer; { long now,diff; struct timeval time; gettimeofday(&time,0); now = time.tv_sec*1000L+(time.tv_usec+500L)/1000L+1L; if (*timer == 0L) diff = 0L; else { diff = now-*timer; if (diff < 0L) diff += 86400000L; /* midnight */ } *timer = now; return diff; } /* * Timer code. Uses polling instead of interrupts which is okay for MS-DOS. */ extern int time_to_call_heart_beat, comm_time_to_call_heart_beat; void start_timer(seconds) int seconds; { milliseconds(&timer); timeout = seconds*1000L; } void timer_expire() { long diff; if (timer == 0) return; diff = milliseconds(&timer); if ((timeout -= diff) > 0) return; comm_time_to_call_heart_beat = 1; } /* * getdomainname fake function. declared in <djgppstd.h> * Note: Linux getdomainname behaves differently (?): * would ret 0 if Ok, and do error(EINVAL) if name > len */ int getdomainname(char *name, int len) { strncpy(name, "MSDOS", len); /* should I ensure zero termination? */ return 0; } /* * gethostname fake function. declared in <djgppstd.h> * was previously define in comm.h as * #define gethostname(n,l) strcpy(n,"PC386+") */ int gethostname(char *name, int len) { strncpy(name, "PC386+", len); return 0; } /* * exp() approximation. Required because there's no 387 emulation for this * function yet. Unfortunately, any better approximation reveals strange * bugs in the emulator. */ double exp(x) double x; { return x <= -1.0 ? 1.0e-10 : 1.0+x; } /* * Very weak replacement for crypt(). */ #if 0 /* Crypt is now in hosts/crypt.c */ #define rot(v,c) (((v) << c) | ((v) >> (8-c))) static int mirror(x) int x; { return ((x & 1) << 7) | ((x & 2) << 5) | ((x & 4) << 3) | ((x & 8) << 1) | ((x & 16) >> 1) | ((x & 32) >> 3) | ((x & 64) >> 5) | ((x & 128) >> 7); } char *crypt(pw,salt) char *pw; char *salt; { static char e64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz.0123456789"; static char enc[9]; char tp[9]; int scrm,i,bpos,n; memset(tp,'\0',8); strncpy(tp,pw,8); tp[0] ^= enc[0] = salt[0]; tp[3] ^= enc[1] = salt[1]; scrm = 165; for (i = 7; i >= 0; i--) scrm = (tp[i] ^= scrm >> 1); for (i = 7; i; i--) tp[tp[i-1] & 7] ^= rot(tp[i],1); for (i = (tp[0] & 127)+19; i; i--) tp[tp[i & 7] & 7] ^= rot(tp[(tp[i & 7] >> 3) & 7],tp[i & 7] >> 6); for (i = 3; i >= 0; i--) tp[i] ^= mirror(tp[7-i]); bpos = 0; for (i = 7; i > 1; i--) { n = ((tp[bpos >> 3] >> (bpos & 7)) | (tp[(bpos >> 3)+1] << (8-(bpos & 7)))) & 63; enc[i] = e64[n]; bpos += 6; } enc[8] = '\0'; return enc; } #endif /* * Checks for legal MS-DOS file names. * WARNING: This breaks if users add their own character devices to DOS. */ #define upper(c) (isupper(c) ? c : toupper(c)) static int is(a,b) /* case-blind test for equality */ char *a,*b; { while (*a || *b) { if (upper(*a) != upper(*b)) return 0; a++; b++; } return 1; } int valid_msdos(path) char *path; { char *name,*here; if (strchr(path,'\\')) return 0; /* better save than sorry ... */ if (strchr(path,':')) return 0; /* \B: is okay for DOS .. *sigh* */ if (name = strrchr(path,'/')) name++; else name = path; if (is(name,"NUL") || is(name,"CON") || is(name,"PRN") || is(name,"AUX") || is(name,"COM1") || is(name,"COM2") || is(name,"COM3") || is(name,"COM4") || is(name,"LPT1") || is(name,"LPT2") || is(name,"LPT3") || is(name,"LPT4")) return 0; if (here = strchr(name,'.')) if (strchr(here+1,'.')) return 0; return 1; } /* * Checks for file identity. Requires SHARE. Works only if no other programs * are accessing the files. */ static void dos_close(fd) int fd; { union REGS r; r.h.ah = 0x3e; r.x.bx = fd; int86(0x21,&r,&r); } int same_file(a,b) char *a,*b; { int fd_a,fd_b,same; if ((fd_a = bdosptr(0x3d,a,0)) < 0) return 0; dos_close(fd_a); if ((fd_b = bdosptr(0x3d,b,0x10)) < 0) return 0; if ((fd_a = bdosptr(0x3d,a,0x10)) < 0) same = 1; else { dos_close(fd_a); same = 0; } dos_close(fd_b); return same; }