⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vms.c

📁 zip压缩
💻 C
📖 第 1 页 / 共 5 页
字号:
    return PK_COOL;}/* *   Routine _flush_stream breaks decompressed stream into records *   depending on format of the stream (fab->rfm, G.pInfo->textmode, etc.) *   and puts out these records. It also handles CR LF sequences. *   Should be used when extracting *text* files. */#define VT      0x0B#define FF      0x0C/* The file is from MSDOS/OS2/NT -> handle CRLF as record end, throw out ^Z *//* GRR NOTES:  cannot depend on hostnum!  May have "flip'd" file or re-zipped * a Unix file, etc. */#ifdef USE_ORIG_DOS# define ORG_DOS \          (G.pInfo->hostnum==FS_FAT_    \        || G.pInfo->hostnum==FS_HPFS_   \        || G.pInfo->hostnum==FS_NTFS_)#else# define ORG_DOS    1#endif/* Record delimiters */#ifdef undef#define RECORD_END(c,f)                                                 \(    ( ORG_DOS || G.pInfo->textmode ) && c==CTRLZ                       \  || ( f == FAB$C_STMLF && c==LF )                                      \  || ( f == FAB$C_STMCR || ORG_DOS || G.pInfo->textmode ) && c==CR      \  || ( f == FAB$C_STM && (c==CR || c==LF || c==FF || c==VT) )           \)#else#   define  RECORD_END(c,f)   ((c) == LF || (c) == (CR))#endifstatic unsigned find_eol(p,n,l)/* *  Find first CR, LF, CR/LF or LF/CR in string 'p' of length 'n'. *  Return offset of the sequence found or 'n' if not found. *  If found, return in '*l' length of the sequence (1 or 2) or *  zero if sequence end not seen, i.e. CR or LF is last char *  in the buffer. */    uch *p;    unsigned n;    unsigned *l;{    unsigned off = n;    uch *q;    *l = 0;    for (q=p ; n > 0 ; --n,++q)        if ( RECORD_END(*q,rfm) )        {            off = q-p;            break;        }    if ( n > 1 )    {        *l = 1;        if ( ( q[0] == CR && q[1] == LF ) || ( q[0] == LF && q[1] == CR ) )            *l = 2;    }    return off;}/* Record delimiters that must be put out */#define PRINT_SPEC(c)   ( (c)==FF || (c)==VT )static int _flush_stream(__G__ rawbuf, size, final_flag)    __GDEF    uch *rawbuf;    unsigned size;    int final_flag; /* 1 if this is the final flushout */{    int rest;    unsigned end = 0, start = 0;    if (size == 0 && loccnt == 0)        return PK_COOL;         /* Nothing to do ... */    if ( final_flag )    {        unsigned recsize;        /*         * This is flush only call. size must be zero now.         * Just eject everything we have in locbuf.         */        recsize = loccnt - (got_eol ? 1 : 0);        /*         *  If the last char of file was ^Z ( end-of-file in MSDOS ),         *  we will see it now.         */        if ( recsize==1 && locbuf[0] == CTRLZ )            return PK_COOL;        return WriteRecord(__G__ locbuf, recsize);    }    if ( loccnt > 0 )    {        /* Find end of record partially saved in locbuf */        unsigned recsize;        int complete=0;        if ( got_eol )        {            recsize = loccnt - 1;            complete = 1;            if ( (got_eol == CR && rawbuf[0] == LF) ||                 (got_eol == LF && rawbuf[0] == CR) )                end = 1;            got_eol = 0;        }        else        {            unsigned eol_len;            unsigned eol_off;            eol_off = find_eol(rawbuf, size, &eol_len);            if ( loccnt+eol_off > BUFSMAXREC )            {                /*                 *  No room in locbuf. Dump it and clear                 */                char buf[80];           /* CANNOT use slide for Info() */                recsize = loccnt;                start = 0;                Info(buf, 1, (buf,                     "[ Warning: Record too long (%u) ]\n", loccnt+eol_off));                complete = 1;                end = 0;            }            else            {                if ( eol_off >= size )                {                    end = size;                    complete = 0;                }                else if ( eol_len == 0 )                {                    got_eol = rawbuf[eol_off];                    end = size;                    complete = 0;                }                else                {                    memcpy(locptr, rawbuf, eol_off);                    recsize = loccnt + eol_off;                    locptr += eol_off;                    loccnt += eol_off;                    end = eol_off + eol_len;                    complete = 1;                }            }        }        if ( complete )        {            if (WriteRecord(__G__ locbuf, recsize))                return PK_DISK;            loccnt = 0;            locptr = locbuf;        }    }                           /* end if ( loccnt ) */    for (start = end; start < size && end < size; )    {        unsigned eol_off, eol_len;        got_eol = 0;#ifdef undef        if (uO.cflag)            /* skip CR's at the beginning of record */            while (start < size && rawbuf[start] == CR)                ++start;#endif        if ( start >= size )            continue;        /* Find record end */        end = start+(eol_off = find_eol(rawbuf+start, size-start, &eol_len));        if ( end >= size )            continue;        if ( eol_len > 0 )        {            if ( WriteRecord(__G__ rawbuf+start, end-start) )                return PK_DISK;            start = end + eol_len;        }        else        {            got_eol = rawbuf[end];            end = size;            continue;        }    }    rest = size - start;    if (rest > 0)    {        if ( rest > BUFSMAXREC )        {            unsigned recsize;            char buf[80];               /* CANNOT use slide for Info() */            recsize = rest - (got_eol ? 1 : 0 );            Info(buf, 1, (buf,                 "[ Warning: Record too long (%u) ]\n", recsize));            got_eol = 0;            return WriteRecord(__G__ rawbuf+start, recsize);        }        else        {            memcpy(locptr, rawbuf + start, rest);            locptr += rest;            loccnt += rest;        }    }    return PK_COOL;}static int WriteBuffer(__G__ buf, len)    __GDEF    uch *buf;    unsigned len;{    int status;    if (uO.cflag)    {        (void)(*G.message)((zvoid *)&G, buf, len, 0);    }    else    {        status = sys$wait(outrab);        if (ERR(status))        {            vms_msg(__G__ "[ WriteBuffer: sys$wait failed ]\n", status);            vms_msg(__G__ "", outrab->rab$l_stv);        }        outrab->rab$w_rsz = len;        outrab->rab$l_rbf = (char *) buf;        if (ERR(status = sys$write(outrab)))        {            vms_msg(__G__ "[ WriteBuffer: sys$write failed ]\n", status);            vms_msg(__G__ "", outrab->rab$l_stv);            return PK_DISK;        }    }    return PK_COOL;}static int WriteRecord(__G__ rec, len)    __GDEF    uch *rec;    unsigned len;{    int status;    if (uO.cflag)    {        (void)(*G.message)((zvoid *)&G, rec, len, 0);        (void)(*G.message)((zvoid *)&G, (uch *) ("\n"), 1, 0);    }    else    {        if (ERR(status = sys$wait(outrab)))        {            vms_msg(__G__ "[ WriteRecord: sys$wait failed ]\n", status);            vms_msg(__G__ "", outrab->rab$l_stv);        }        outrab->rab$w_rsz = len;        outrab->rab$l_rbf = (char *) rec;        if (ERR(status = sys$put(outrab)))        {            vms_msg(__G__ "[ WriteRecord: sys$put failed ]\n", status);            vms_msg(__G__ "", outrab->rab$l_stv);            return PK_DISK;        }    }    return PK_COOL;}void close_outfile(__G)    __GDEF{    int status;    status = (*_flush_routine)(__G__ NULL, 0, 1);    if (status)        return /* PK_DISK */;    if (uO.cflag)        return /* PK_COOL */;   /* Don't close stdout */    /* return */ (*_close_routine)(__G);}static int _close_rms(__GPRO){    int status;    struct XABPRO pro;    /* Link XABRDT, XABDAT and optionally XABPRO */    if (xabrdt != NULL)    {        xabrdt->xab$l_nxt = NULL;        outfab->fab$l_xab = (void *) xabrdt;    }    else    {        rdt.xab$l_nxt = NULL;        outfab->fab$l_xab = (void *) &rdt;    }    if (xabdat != NULL)    {        xabdat->xab$l_nxt = outfab->fab$l_xab;        outfab->fab$l_xab = (void *)xabdat;    }    if (xabpro != NULL)    {        if ( !uO.X_flag )            xabpro->xab$l_uic = 0;    /* Use default (user's) uic */        xabpro->xab$l_nxt = outfab->fab$l_xab;        outfab->fab$l_xab = (void *) xabpro;    }    else    {        pro = cc$rms_xabpro;        pro.xab$w_pro = G.pInfo->file_attr;        pro.xab$l_nxt = outfab->fab$l_xab;        outfab->fab$l_xab = (void *) &pro;    }    status = sys$wait(outrab);    if (ERR(status))    {        vms_msg(__G__ "[ _close_rms: sys$wait failed ]\n", status);        vms_msg(__G__ "", outrab->rab$l_stv);    }    status = sys$close(outfab);#ifdef DEBUG    if (ERR(status))    {        vms_msg(__G__          "\r[ Warning: cannot set owner/protection/time attributes ]\n",          status);        vms_msg(__G__ "", outfab->fab$l_stv);    }#endif    free_up();    return PK_COOL;}static int _close_qio(__GPRO){    int status;    pka_fib.FIB$L_ACCTL =        FIB$M_WRITE | FIB$M_NOTRUNC ;    pka_fib.FIB$W_EXCTL = 0;    pka_fib.FIB$W_FID[0] =    pka_fib.FIB$W_FID[1] =    pka_fib.FIB$W_FID[2] =    pka_fib.FIB$W_DID[0] =    pka_fib.FIB$W_DID[1] =    pka_fib.FIB$W_DID[2] = 0;#ifdef ASYNCH_QIO    if (pka_io_pending) {        status = sys$synch(0, &pka_io_sb);        if (!ERR(status))            status = pka_io_sb.status;        if (ERR(status))        {            vms_msg(__G__ "[ _close_qio: sys$synch found I/O failure ]\n",                    status);        }        pka_io_pending = FALSE;    }#endif /* ASYNCH_QIO */    status = sys$qiow(0, pka_devchn, IO$_DEACCESS, &pka_acp_sb,                      0, 0,                      &pka_fibdsc, 0, 0, 0,                      &pka_atr, 0);    sys$dassgn(pka_devchn);    if ( !ERR(status) )        status = pka_acp_sb.status;    if ( ERR(status) )    {        vms_msg(__G__ "[ Deaccess QIO failed ]\n", status);        return PK_DISK;    }    return PK_COOL;}#ifdef TIMESTAMP/* Nonzero if `y' is a leap year, else zero. */#define leap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0)/* Number of leap years from 1970 to `y' (not including `y' itself). */#define nleap(y) (((y) - 1969) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400)/* Accumulated number of days from 01-Jan up to start of current month. */static ZCONST short ydays[] = {    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};/***********************//* Function mkgmtime() *//***********************/static time_t mkgmtime(tm)    struct tm *tm;{    time_t m_time;    int yr, mo, dy, hh, mm, ss;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -