?? vms.c
字號:
unsigned days; yr = tm->tm_year - 70; mo = tm->tm_mon; dy = tm->tm_mday - 1; hh = tm->tm_hour; mm = tm->tm_min; ss = tm->tm_sec; /* calculate days from BASE to this year and add expired days this year */ dy = (unsigned)dy + ((unsigned)yr * 365) + (unsigned)nleap(yr+1970) + (unsigned)ydays[mo] + ((mo > 1) && leap(yr+1970)); /* convert date & time to seconds relative to 00:00:00, 01/01/1970 */ return (time_t)((unsigned long)(unsigned)dy * 86400L + (unsigned long)hh * 3600L + (unsigned long)(mm * 60 + ss));} /* end function mkgmtime() *//*******************************//* Function dos_to_unix_time() */ /* only used for timestamping of archives *//*******************************/time_t dos_to_unix_time(dosdatetime) ulg dosdatetime;{ struct tm *ltm; /* Local time. */ time_t loctime; /* The time_t value of local time. */ time_t then; /* The time to return. */ long tzoffset_adj; /* timezone-adjustment `remainder' */ int bailout_cnt; /* counter of tries for tz correction */ then = time(NULL); ltm = localtime(&then); /* dissect date */ ltm->tm_year = ((int)(dosdatetime >> 25) & 0x7f) + 80; ltm->tm_mon = ((int)(dosdatetime >> 21) & 0x0f) - 1; ltm->tm_mday = ((int)(dosdatetime >> 16) & 0x1f); /* dissect time */ ltm->tm_hour = (int)(dosdatetime >> 11) & 0x1f; ltm->tm_min = (int)(dosdatetime >> 5) & 0x3f; ltm->tm_sec = (int)(dosdatetime << 1) & 0x3e; loctime = mkgmtime(ltm); /* Correct for the timezone and any daylight savings time. The correction is verified and repeated when not correct, to take into account the rare case that a change to or from daylight savings time occurs between when it is the time in `tm' locally and when it is that time in Greenwich. After the second correction, the "timezone & daylight" offset should be correct in all cases. To be sure, we allow a third try, but then the loop is stopped. */ bailout_cnt = 3; then = loctime; do { ltm = localtime(&then); tzoffset_adj = (ltm != NULL) ? (loctime - mkgmtime(ltm)) : 0L; if (tzoffset_adj == 0L) break; then += tzoffset_adj; } while (--bailout_cnt > 0); if ( (dosdatetime >= DOSTIME_2038_01_18) && (then < (time_t)0x70000000L) ) then = U_TIME_T_MAX; /* saturate in case of (unsigned) overflow */ if (then < (time_t)0L) /* a converted DOS time cannot be negative */ then = S_TIME_T_MAX; /* -> saturate at max signed time_t value */ return then;} /* end function dos_to_unix_time() *//*******************************//* Function uxtime2vmstime() *//*******************************/static void uxtime2vmstime( /* convert time_t value into 64 bit VMS bintime */ time_t utimeval, long int binval[2] ){ time_t m_time = utimeval; struct tm *t = localtime(&m_time); if (t == (struct tm *)NULL) { /* time conversion error; use current time instead, hoping that localtime() does not reject it as well! */ m_time = time(NULL); t = localtime(&m_time); } sprintf(timbuf, "%02d-%3s-%04d %02d:%02d:%02d.00", t->tm_mday, month[t->tm_mon], t->tm_year + 1900, t->tm_hour, t->tm_min, t->tm_sec); sys$bintim(&date_str, binval);} /* end function uxtime2vmstime() *//***************************//* Function stamp_file() */ /* adapted from VMSmunch...it just won't die! *//***************************/int stamp_file(fname, modtime) ZCONST char *fname; time_t modtime;{ int status; int i; static long int Cdate[2], Rdate[2], Edate[2], Bdate[2]; static short int revisions;#if defined(__DECC) || defined(__DECCXX)#pragma __member_alignment __save#pragma __nomember_alignment#endif /* __DECC || __DECCXX */ static union { unsigned short int value; struct { unsigned system : 4; unsigned owner : 4; unsigned group : 4; unsigned world : 4; } bits; } prot;#if defined(__DECC) || defined(__DECCXX)#pragma __member_alignment __restore#endif /* __DECC || __DECCXX */ static unsigned long uic; static struct fjndef jnl; static struct atrdef Atr[] = { {sizeof(pka_rattr), ATR$C_RECATTR, &pka_rattr}, {sizeof(pka_uchar), ATR$C_UCHAR, &pka_uchar}, {sizeof(Cdate), ATR$C_CREDATE, &Cdate[0]}, {sizeof(Rdate), ATR$C_REVDATE, &Rdate[0]}, {sizeof(Edate), ATR$C_EXPDATE, &Edate[0]}, {sizeof(Bdate), ATR$C_BAKDATE, &Bdate[0]}, {sizeof(revisions), ATR$C_ASCDATES, &revisions}, {sizeof(prot), ATR$C_FPRO, &prot}, {sizeof(uic), ATR$C_UIC, &uic}, {sizeof(jnl), ATR$C_JOURNAL, &jnl}, {0, 0, 0} }; fileblk = cc$rms_fab; fileblk.fab$l_fna = (char *)fname; fileblk.fab$b_fns = strlen(fname); nam = cc$rms_nam; fileblk.fab$l_nam = &nam; nam.nam$l_esa = exp_nam; nam.nam$b_ess = sizeof(exp_nam); nam.nam$l_rsa = res_nam; nam.nam$b_rss = sizeof(res_nam); if ( ERR(status = sys$parse(&fileblk)) ) { vms_msg(__G__ "stamp_file: sys$parse failed.\n", status); return -1; } pka_devdsc.dsc$w_length = (unsigned short)nam.nam$t_dvi[0]; if ( ERR(status = sys$assign(&pka_devdsc,&pka_devchn,0,0)) ) { vms_msg(__G__ "stamp_file: sys$assign failed.\n", status); return -1; } pka_fnam.dsc$a_pointer = nam.nam$l_name; pka_fnam.dsc$w_length = nam.nam$b_name + nam.nam$b_type + nam.nam$b_ver; for (i=0;i<3;i++) { pka_fib.FIB$W_DID[i]=nam.nam$w_did[i]; pka_fib.FIB$W_FID[i]=nam.nam$w_fid[i]; } /* Use the IO$_ACCESS function to return info about the file */ /* Note, used this way, the file is not opened, and the expiration */ /* and revision dates are not modified */ status = sys$qiow(0, pka_devchn, IO$_ACCESS, &pka_acp_sb, 0, 0, &pka_fibdsc, &pka_fnam, 0, 0, &Atr, 0); if ( !ERR(status) ) status = pka_acp_sb.status; if ( ERR(status) ) { vms_msg(__G__ "[ Access file QIO failed. ]\n", status); sys$dassgn(pka_devchn); return -1; } uxtime2vmstime(modtime, Cdate); memcpy(Rdate, Cdate, sizeof(Cdate)); /* note, part of the FIB was cleared by earlier QIOW, so reset it */ pka_fib.FIB$L_ACCTL = FIB$M_NORECORD; for (i=0;i<3;i++) { pka_fib.FIB$W_DID[i]=nam.nam$w_did[i]; pka_fib.FIB$W_FID[i]=nam.nam$w_fid[i]; } /* Use the IO$_MODIFY function to change info about the file */ /* Note, used this way, the file is not opened, however this would */ /* normally cause the expiration and revision dates to be modified. */ /* Using FIB$M_NORECORD prohibits this from happening. */ status = sys$qiow(0, pka_devchn, IO$_MODIFY, &pka_acp_sb, 0, 0, &pka_fibdsc, &pka_fnam, 0, 0, &Atr, 0); if ( !ERR(status) ) status = pka_acp_sb.status; if ( ERR(status) ) { vms_msg(__G__ "[ Modify file QIO failed. ]\n", status); sys$dassgn(pka_devchn); return -1; } if ( ERR(status = sys$dassgn(pka_devchn)) ) { vms_msg(__G__ "stamp_file: sys$dassgn failed.\n", status); return -1; } return 0;} /* end function stamp_file() */#endif /* TIMESTAMP */#ifdef DEBUG#if 0 /* currently not used anywhere ! */void dump_rms_block(p) unsigned char *p;{ unsigned char bid, len; int err; char *type; char buf[132]; int i; err = 0; bid = p[0]; len = p[1]; switch (bid) { case FAB$C_BID: type = "FAB"; break; case XAB$C_ALL: type = "xabALL"; break; case XAB$C_KEY: type = "xabKEY"; break; case XAB$C_DAT: type = "xabDAT"; break; case XAB$C_RDT: type = "xabRDT"; break; case XAB$C_FHC: type = "xabFHC"; break; case XAB$C_PRO: type = "xabPRO"; break; default: type = "Unknown"; err = 1; break; } printf("Block @%08X of type %s (%d).", p, type, bid); if (err) { printf("\n"); return; } printf(" Size = %d\n", len); printf(" Offset - Hex - Dec\n"); for (i = 0; i < len; i += 8) { int j; printf("%3d - ", i); for (j = 0; j < 8; j++) if (i + j < len) printf("%02X ", p[i + j]); else printf(" "); printf(" - "); for (j = 0; j < 8; j++) if (i + j < len) printf("%03d ", p[i + j]); else printf(" "); printf("\n"); }}#endif /* never */#endif /* DEBUG */static void vms_msg(__GPRO__ char *string, int status){ static char msgbuf[256]; $DESCRIPTOR(msgd, msgbuf); int msglen = 0; if (ERR(lib$sys_getmsg(&status, &msglen, &msgd, 0, 0))) Info(slide, 1, ((char *)slide, "%s[ VMS status = %d ]\n", string, status)); else { msgbuf[msglen] = '\0'; Info(slide, 1, ((char *)slide, "%s[ %s ]\n", string, msgbuf)); }}#ifndef SFXchar *do_wild( __G__ wld ) __GDEF ZCONST char *wld;{ int status; static char filenam[256]; static char efn[256]; static char last_wild[256]; static struct FAB fab; static struct NAM nam; static int first_call=1; static ZCONST char deflt[] = "[]*.zip"; if ( first_call || strcmp(wld, last_wild) ) { /* (Re)Initialize everything */ strcpy( last_wild, wld ); first_call = 1; /* New wild spec */ fab = cc$rms_fab; fab.fab$l_fna = last_wild; fab.fab$b_fns = strlen(last_wild); fab.fab$l_dna = (char *) deflt; fab.fab$b_dns = sizeof(deflt)-1; fab.fab$l_nam = &nam; nam = cc$rms_nam; nam.nam$l_esa = efn; nam.nam$b_ess = sizeof(efn)-1; nam.nam$l_rsa = filenam; nam.nam$b_rss = sizeof(filenam)-1; if ( !OK(sys$parse(&fab)) ) return (char *)NULL; /* Initialization failed */ first_call = 0; if ( !OK(sys$search(&fab)) ) { strcpy( filenam, wld ); return filenam; } } else { if ( !OK(sys$search(&fab)) ) { first_call = 1; /* Reinitialize next time */ return (char *)NULL; } } filenam[nam.nam$b_rsl] = 0; return filenam;} /* end function do_wild() */#endif /* !SFX */static ulg unix_to_vms[8]={ /* Map from UNIX rwx to VMS rwed */ /* Note that unix w bit is mapped to VMS wd bits */ /* no access */ XAB$M_NOREAD | XAB$M_NOWRITE | XAB$M_NODEL | XAB$M_NOEXE, /* --- */ XAB$M_NOREAD | XAB$M_NOWRITE | XAB$M_NODEL, /* --x */ XAB$M_NOREAD | XAB$M_NOEXE, /* -w- */ XAB$M_NOREAD, /* -wx */ XAB$M_NOWRITE | XAB$M_NODEL | XAB$M_NOEXE, /* r-- */ XAB$M_NOWRITE | XAB$M_NODEL, /* r-x */ XAB$M_NOEXE, /* rw- */ 0 /* rwx */ /* full access */};#define SETDFPROT /* We are using undocumented VMS System Service */ /* SYS$SETDFPROT here. If your version of VMS does */ /* not have that service, undef SETDFPROT. */ /* IM: Maybe it's better to put this to Makefile */ /* and DESCRIP.MMS */#ifdef SETDFPROTextern int SYS$SETDFPROT();#endifint mapattr(__G) __GDEF{ ulg tmp = G.crec.external_file_attributes; ulg theprot; static ulg defprot = (ulg)-1L, sysdef,owndef,grpdef,wlddef; /* Default protection fields */ /* IM: The only field of XABPRO we need to set here is */ /* file protection, so we need not to change type */ /* of G.pInfo->file_attr. WORD is quite enough. */ if ( defprot == (ulg)-1L ) { /* * First time here -- Get user default settings */#ifdef SETDFPROT /* Undef this if linker cat't resolve SYS$SETDFPROT */ defprot = (ulg)0L; if ( !ERR(SYS$SETDFPROT(0,&defprot)) ) { sysdef = defprot & ( (1L<<XAB$S_SYS)-1 ) << XAB$V_SYS; owndef = defprot & ( (1L<<XAB$S_OWN)-1 ) << XAB$V_OWN; grpdef = defprot & ( (1L<<XAB$S_GRP)-1 ) << XAB$V_GRP; wlddef = defprot & ( (1L<<XAB$S_WLD)-1 ) << XAB$V_WLD; } else#endif /* SETDFPROT */ { umask(defprot = umask(0)); defprot = ~defprot; wlddef = unix_to_vms[defprot & 07] << XAB$V_WLD; grpdef = unix_to_vms[(defprot>>3) & 07] << XAB$V_GRP; owndef = unix_to_vms[(defprot>>6) & 07] << XAB$V_OWN;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -