X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=ndmp-src%2Fsmc_parse.c;fp=ndmp-src%2Fsmc_parse.c;h=29bc504135bf6168066f58ea6da187ad6148e900;hb=fd48f3e498442f0cbff5f3606c7c403d0566150e;hp=0000000000000000000000000000000000000000;hpb=96f35b20267e8b1a1c846d476f27fcd330e0b018;p=debian%2Famanda diff --git a/ndmp-src/smc_parse.c b/ndmp-src/smc_parse.c new file mode 100644 index 0000000..29bc504 --- /dev/null +++ b/ndmp-src/smc_parse.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 1998,1999,2000 + * Traakan, Inc., Los Altos, CA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Project: NDMJOB + * Ident: $Id: $ + * + * Description: + * + */ + + +#include "smc_priv.h" + + +#define WITH(P,V,T) { T * V = (T *) P; +#define ENDWITH } + +int +smc_parse_volume_tag ( + struct smc_raw_volume_tag *raw, + struct smc_volume_tag *vtag) +{ + int i; + + bzero (vtag, sizeof *vtag); + + for (i = 31; i >= 0 && raw->volume_id[i] == ' '; i--) + continue; + + for (; i >= 0; i--) + vtag->volume_id[i] = raw->volume_id[i]; + + vtag->volume_seq = SMC_GET2(raw->volume_seq); + + return 0; +} + + + +int +smc_parse_element_status_data ( + char * raw, + unsigned raw_len, + struct smc_element_descriptor elem_desc[], + unsigned max_elem_desc) +{ + unsigned char * p = (unsigned char *)raw; + unsigned char * raw_end = p + raw_len; + unsigned int n_elem = 0; + + bzero (elem_desc, sizeof elem_desc[0] * max_elem_desc); + + WITH(p, esdh, struct smc_raw_element_status_data_header) + unsigned byte_count = SMC_GET3(esdh->byte_count); + + if (raw_len > byte_count+8) { + /* probably an error, but press on */ + raw_len = byte_count+8; + } + raw_end = p + raw_len; + ENDWITH + + p += 8; + + while (p+8 < raw_end) { /* +8 for sizeof *esph */ + WITH(p, esph, struct smc_raw_element_status_page_header) + unsigned desc_size = SMC_GET2(esph->elem_desc_len); + unsigned byte_count = SMC_GET3(esph->byte_count); + unsigned elem_type = esph->element_type; + unsigned char * pgend = p + byte_count + 8; + int PVolTag = 0; + int AVolTag = 0; + + if (pgend > raw_end) { + /* malformed, really, but punt */ + pgend = raw_end; + } + + if (esph->flag1 & SMC_RAW_ESP_F1_PVolTag) + PVolTag = 1; + if (esph->flag1 & SMC_RAW_ESP_F1_AVolTag) + AVolTag = 1; + + p += 8; + + for (;p + desc_size <= pgend; p += desc_size) { + struct smc_element_descriptor *edp; + + if (n_elem >= max_elem_desc) { + /* bust out */ + goto done; + } + edp = &elem_desc[n_elem++]; + WITH (p, red, struct smc_raw_element_descriptor) + unsigned char *p2; + + edp->element_type_code = elem_type; + edp->element_address = SMC_GET2(red->element_address); + edp->PVolTag = PVolTag; + edp->AVolTag = AVolTag; +#define FLAG(RAWMEM,BIT,MEM) if (red->RAWMEM & BIT) edp->MEM = 1; + FLAG(flags2, SMC_RAW_ED_F2_Full, Full); + FLAG(flags2, SMC_RAW_ED_F2_ImpExp, ImpExp); + FLAG(flags2, SMC_RAW_ED_F2_Except, Except); + FLAG(flags2, SMC_RAW_ED_F2_Access, Access); + FLAG(flags2, SMC_RAW_ED_F2_ExEnab, ExEnab); + FLAG(flags2, SMC_RAW_ED_F2_InEnab, InEnab); + + edp->asc = red->asc; + edp->ascq = red->ascq; + + edp->scsi_lun = red->flags6 & 7; + FLAG(flags6, SMC_RAW_ED_F6_LU_valid, LU_valid); + FLAG(flags6, SMC_RAW_ED_F6_ID_valid, ID_valid); + FLAG(flags6, SMC_RAW_ED_F6_Not_bus, Not_bus); + + edp->scsi_sid = red->scsi_sid; + + FLAG(flags9, SMC_RAW_ED_F9_Invert, Invert); + FLAG(flags9, SMC_RAW_ED_F9_SValid, SValid); +#undef FLAG + + edp->src_se_addr = SMC_GET2(red->src_se_addr); + + p2 = (unsigned char *) &red->primary_vol_tag; + if (edp->PVolTag) { + smc_parse_volume_tag ((void*)p2, + &edp->primary_vol_tag); + p2 += SMC_VOL_TAG_LEN; + } + if (edp->AVolTag) { + smc_parse_volume_tag ((void*)p2, + &edp->alternate_vol_tag); + p2 += SMC_VOL_TAG_LEN; + } + p2 += 4; /* resv84 */ + /* p2 ready for vendor_specific */ + ENDWITH + } + p = pgend; + ENDWITH + } + + done: + return n_elem; +} + + + +int +smc_parse_element_address_assignment ( + struct smc_raw_element_address_assignment_page *raw, + struct smc_element_address_assignment *eaa) +{ + eaa->mte_addr = SMC_GET2(raw->mte_addr); + eaa->mte_count = SMC_GET2(raw->mte_count); + eaa->se_addr = SMC_GET2(raw->se_addr); + eaa->se_count = SMC_GET2(raw->se_count); + eaa->iee_addr = SMC_GET2(raw->iee_addr); + eaa->iee_count = SMC_GET2(raw->iee_count); + eaa->dte_addr = SMC_GET2(raw->dte_addr); + eaa->dte_count = SMC_GET2(raw->dte_count); + + return 0; +} +