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

📄 vms.c

📁 压缩解压,是unzip540的升级,这个外国网站摘来的源码,是evb编写.
💻 C
📖 第 1 页 / 共 5 页
字号:
{    int status;    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__ "[ WriteQIO: sys$synch found I/O failure ]\n",                    status);            return PK_DISK;        }        pka_io_pending = FALSE;    }    /*     *   Put content of buffer as a single VB     */    status = sys$qio(0, pka_devchn, IO$_WRITEVBLK,                     &pka_io_sb, 0, 0,                     buf, len, pka_vbn,                     0, 0, 0);    if (ERR(status))    {        vms_msg(__G__ "[ WriteQIO: sys$qio failed ]\n", status);        return PK_DISK;    }    pka_io_pending = TRUE;    pka_vbn += (len>>9);    return PK_COOL;}/*   2004-10-01 SMS.  Changed to clear the extra byte written out by qio()   and sys$write() when an odd byte count is incremented to the next   even value, either explicitly (qio), or implicitly (sys$write), on   the theory that a reliable NUL beats left-over garbage.  Alpha and   VAX object files seem frequently to have even more than one byte of   extra junk past EOF, so this may not help them.*/static int _flush_qio(__G__ rawbuf, size, final_flag)                                                /* Asynchronous version */    __GDEF    uch *rawbuf;    unsigned size;    int final_flag;   /* 1 if this is the final flushout */{    int status;    unsigned off = 0;    while (size > 0)    {        if (curbuf->bufcnt < BUFS512)        {            unsigned ncpy;            ncpy = size > (BUFS512 - curbuf->bufcnt) ?                   (BUFS512 - curbuf->bufcnt) : size;            memcpy(curbuf->buf + curbuf->bufcnt, rawbuf + off, ncpy);            size -= ncpy;            curbuf->bufcnt += ncpy;            off += ncpy;        }        if (curbuf->bufcnt == BUFS512)        {            status = WriteQIO(__G__ curbuf->buf, curbuf->bufcnt);            if (status)                return status;            curbuf = curbuf->next;            curbuf->bufcnt = 0;        }    }    if (final_flag && (curbuf->bufcnt > 0))    {        unsigned bufcnt_even;        /* Round up to an even byte count. */        bufcnt_even = (curbuf->bufcnt+1) & (~1);        /* If there is one, clear the extra byte. */        if (bufcnt_even > curbuf->bufcnt)            curbuf->buf[curbuf->bufcnt] = '\0';        return WriteQIO(curbuf->buf, bufcnt_even);    }    else    {        return PK_COOL;    }}#else /* !ASYNCH_QIO */static int _flush_qio(__G__ rawbuf, size, final_flag)    __GDEF    uch *rawbuf;    unsigned size;    int final_flag;   /* 1 if this is the final flushout */{    int status;    uch *out_ptr=rawbuf;    if ( final_flag )    {        if ( loccnt > 0 )        {            unsigned loccnt_even;            /* Round up to an even byte count. */            loccnt_even = (loccnt+1) & (~1);            /* If there is one, clear the extra byte. */            if (loccnt_even > loccnt)                locbuf[ loccnt] = '\0';            status = sys$qiow(0, pka_devchn, IO$_WRITEVBLK,                              &pka_io_sb, 0, 0,                              locbuf,                              loccnt_even,                              pka_vbn,                              0, 0, 0);            if (!ERR(status))                status = pka_io_sb.status;            if (ERR(status))            {                vms_msg(__G__ "[ Write QIO failed ]\n", status);                return PK_DISK;            }        }        return PK_COOL;    }    if ( loccnt > 0 )    {        /*         *   Fill local buffer upto 512 bytes then put it out         */        unsigned ncpy;        ncpy = 512-loccnt;        if ( ncpy > size )            ncpy = size;        memcpy(locptr, out_ptr, ncpy);        locptr += ncpy;        loccnt += ncpy;        size -= ncpy;        out_ptr += ncpy;        if ( loccnt == 512 )        {            status = sys$qiow(0, pka_devchn, IO$_WRITEVBLK,                              &pka_io_sb, 0, 0,                              locbuf, loccnt, pka_vbn,                              0, 0, 0);            if (!ERR(status))                status = pka_io_sb.status;            if (ERR(status))            {                vms_msg(__G__ "[ Write QIO failed ]\n", status);                return PK_DISK;            }            pka_vbn++;            loccnt = 0;            locptr = locbuf;        }    }    if ( size >= 512 )    {        unsigned nblk, put_cnt;        /*         *   Put rest of buffer as a single VB         */        put_cnt = (nblk = size>>9)<<9;        status = sys$qiow(0, pka_devchn, IO$_WRITEVBLK,                          &pka_io_sb, 0, 0,                          out_ptr, put_cnt, pka_vbn,                          0, 0, 0);        if (!ERR(status))            status = pka_io_sb.status;        if (ERR(status))        {            vms_msg(__G__ "[ Write QIO failed ]\n", status);            return PK_DISK;        }        pka_vbn += nblk;        out_ptr += put_cnt;        size -= put_cnt;    }    if ( size > 0 )    {        memcpy(locptr, out_ptr, size);        loccnt += size;        locptr += size;    }    return PK_COOL;}#endif /* ?ASYNCH_QIO *//* * The routine _flush_varlen() requires: "(size & 1) == 0" * (The variable-length record algorithm assumes an even byte-count!) */static int _flush_varlen(__G__ rawbuf, size, final_flag)    __GDEF    uch *rawbuf;    unsigned size;    int final_flag;{    unsigned nneed;    unsigned reclen;    uch *inptr=rawbuf;    /*     * Flush local buffer     */    if ( loccnt > 0 )           /* incomplete record left from previous call */    {        reclen = *(ush*)locbuf;        nneed = reclen + 2 - loccnt;        if ( nneed > size )        {            if ( size+loccnt > BUFSMAXREC )            {                char buf[80];                Info(buf, 1, (buf,                     "[ Record too long (%u bytes) ]\n", reclen));                return PK_DISK;            }            memcpy(locbuf+loccnt, inptr, size);            loccnt += size;            size = 0;        }        else        {            memcpy(locbuf+loccnt, inptr, nneed);            loccnt += nneed;            size -= nneed;            inptr += nneed;            if ( reclen & 1 )            {                size--;                inptr++;            }            if ( WriteRecord(__G__ locbuf+2, reclen) )                return PK_DISK;            loccnt = 0;        }    }    /*     * Flush incoming records     */    while (size > 0)    {        reclen = *(ush*)inptr;        if ( reclen+2 <= size )        {            if (WriteRecord(__G__ inptr+2, reclen))                return PK_DISK;            size -= 2+reclen;            inptr += 2+reclen;            if ( reclen & 1 )            {                --size;                ++inptr;            }        }        else        {            memcpy(locbuf, inptr, size);            loccnt = size;            size = 0;        }    }    /*     * Final flush rest of local buffer     */    if ( final_flag && loccnt > 0 )    {        char buf[80];        Info(buf, 1, (buf,             "[ Warning, incomplete record of length %u ]\n",             (unsigned)*(ush*)locbuf));        if ( WriteRecord(__G__ locbuf+2, loccnt-2) )            return PK_DISK;    }    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 )

⌨️ 快捷键说明

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