Back to index

im-sdk  12.3.91
im-connect.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <sys/types.h>
00004 
00005 #include <iiimp-data.h>
00006 #include <iiimp-opcode.h>
00007 
00008 #include "iiimp-dataP.h"
00009 
00010 
00011 IIIMP_message *
00012 iiimp_connect_new(
00013     IIIMP_data_s *   data_s,
00014     IIIMP_string *   user_name,
00015     IIIMP_string *   auth)
00016 {
00017     IIIMP_message *  m;
00018     int                     i;
00019     m = (IIIMP_message *)malloc(sizeof (IIIMP_message));
00020     if (NULL == m) {
00021        data_s->status = IIIMP_DATA_MALLOC_ERROR;
00022        return NULL;
00023     }
00024     m->opcode = IM_CONNECT;
00025     m->im_id = -1;
00026     m->ic_id = -1;
00027     i = 1;
00028     m->v.connect.byte_order = ((0x01 == *((char *)(&i))) ?
00029                             IM_CONNECT_LITTLE_ENDIAN :
00030                             IM_CONNECT_BIG_ENDIAN);
00031     m->v.connect.protocol_version = data_s->protocol_version;
00032     m->v.connect.user_name = user_name;
00033     m->v.connect.auth = auth;
00034     return m;
00035 }
00036 
00037 
00038 void
00039 iiimp_connect_delete(IIIMP_data_s * data_s, IIIMP_message * m)
00040 {
00041     if (NULL == m) return;
00042     iiimp_string_delete(data_s, m->v.connect.user_name);
00043     iiimp_string_list_delete(data_s, m->v.connect.auth);
00044     free(m);
00045     return;
00046 }
00047 
00048 
00049 uchar_t *
00050 iiimp_connect_pack(
00051     IIIMP_data_s *   data_s,
00052     IIIMP_string *   user_name,
00053     IIIMP_string *   auth_protocol,
00054     size_t *         buf_size)
00055 {
00056     size_t           nbyte;
00057     int                     length;
00058     uchar_t *        buf;
00059     size_t           rest;
00060     uchar_t *        p;
00061     IIIMP_card8             byte_order;
00062     int                     i;
00063     IIIMP_string *   a;
00064     size_t           auth_nbyte;
00065 
00066     nbyte = 0;
00067     nbyte += (1 + 1);              /* byte order + protocol version */
00068     nbyte += user_name->nbyte;     /* user name */
00069     nbyte += 2;                    /* byte length of client auth protocol names */
00070     for (auth_nbyte = 0, a = auth_protocol; NULL != a; a = a->next) {
00071        auth_nbyte += a->nbyte;
00072     }
00073     nbyte += auth_nbyte;    /* client auth protocol names */
00074 
00075     length = (nbyte >> 2);
00076     *buf_size = (1 + 3 + nbyte);
00077 
00078     buf = (uchar_t *)malloc(1 + 3 + nbyte);
00079     if (NULL == buf) {
00080        data_s->status = IIIMP_DATA_MALLOC_ERROR;
00081        return NULL;
00082     }
00083 
00084     PUT_PACKET_HEADER(buf, IM_CONNECT, length);
00085 
00086     rest = nbyte;
00087     p = (buf + 4);
00088 
00089     i = 1;
00090     byte_order = ((0x01 == *((char *)(&i))) ?
00091                 IM_CONNECT_LITTLE_ENDIAN :
00092                 IM_CONNECT_BIG_ENDIAN);
00093 
00094     PUTU8(byte_order, rest, p, data_s->byte_swap);
00095     PUTU8(data_s->protocol_version, rest, p, data_s->byte_swap);
00096     iiimp_string_pack(data_s, user_name, &rest, &p);
00097     PUTU16(auth_nbyte, rest, p, data_s->byte_swap);
00098     iiimp_string_list_pack(data_s, auth_protocol, &rest, &p);
00099 
00100     return buf;
00101 }
00102 
00103 
00104 IIIMP_message *
00105 iiimp_connect_unpack(
00106     IIIMP_data_s *   data_s,
00107     IIIMP_card7             opcode,
00108     size_t *         nbyte,
00109     const uchar_t ** ptr)
00110 {
00111     IIIMP_message *  m;
00112     IIIMP_connect_v *       v;
00113     size_t           rest;
00114     const uchar_t *  p;
00115     int                     len;
00116     int                     endian;
00117     int                     protocol_version;
00118 
00119     rest = *nbyte;
00120     p = *ptr;
00121 
00122     if (rest < (1 + 1 + 4 + 2)) {
00123        data_s->status = IIIMP_DATA_INVALID;
00124        return NULL;
00125     }
00126 
00127     m = (IIIMP_message *)malloc(sizeof (IIIMP_message));
00128     if (NULL == m) {
00129        data_s->status = IIIMP_DATA_MALLOC_ERROR;
00130        return NULL;
00131     }
00132     v = &(m->v.connect);
00133 
00134     m->opcode = opcode;
00135     m->im_id = -1;
00136     m->ic_id = -1;
00137     v->user_name = NULL;
00138     v->auth = NULL;
00139 
00140     GETU8(v->byte_order, rest, p, 0);
00141     endian = 0x01;
00142     if (0x01 == (*(uchar_t *)(&endian))) {
00143        /* little endian */
00144        if (IM_CONNECT_BIG_ENDIAN == v->byte_order) {
00145            data_s->byte_swap = 1;
00146        } else {
00147            data_s->byte_swap = 0;
00148        }
00149     } else {
00150        /* big endian */
00151        if (IM_CONNECT_BIG_ENDIAN == v->byte_order) {
00152            data_s->byte_swap = 0;
00153        } else {
00154            data_s->byte_swap = 1;
00155        }
00156     }
00157     if ((IM_CONNECT_BIG_ENDIAN != v->byte_order) &&
00158        (IM_CONNECT_LITTLE_ENDIAN != v->byte_order)) {
00159        free(m);
00160        data_s->status = IIIMP_DATA_INVALID;
00161        return NULL;
00162     }
00163 
00164     GETU8(v->protocol_version, rest, p, data_s->byte_swap);
00165 
00166     if (v->protocol_version == 0x31) {
00167        /* Unfortunately, some old client sends '1'(0x31)
00168           as a version number.   We regard it as version 1.  */
00169        protocol_version = 1;
00170     } else {
00171        protocol_version = v->protocol_version;
00172     }
00173 
00174     if (protocol_version < data_s->protocol_version) {
00175        /* If the requested version is lower than the supported version,
00176           downgrade it.  */
00177        data_s->protocol_version = protocol_version;
00178     }
00179 
00180     v->user_name = iiimp_string_unpack(data_s, &rest, &p, rest);
00181     if ((NULL == v->user_name) || (rest < 2)) {
00182        iiimp_connect_delete(data_s, m);
00183        return NULL;
00184     }
00185 
00186     GETU16(len, rest, p, data_s->byte_swap);
00187     if ((len < 0) || (rest < len)) {
00188        iiimp_connect_delete(data_s, m);
00189        data_s->status = IIIMP_DATA_INVALID;
00190        return NULL;
00191     }
00192     if (0 < len) {
00193        v->auth = iiimp_string_list_unpack(data_s, &rest, &p, len);
00194        if (NULL == v->auth) {
00195            iiimp_connect_delete(data_s, m);
00196            return NULL;
00197        }
00198     }
00199 
00200     return m;
00201 }
00202 
00203 
00204 void
00205 iiimp_connect_print(
00206     IIIMP_data_s *   data_s,
00207     IIIMP_message *  m)
00208 {
00209     IIIMP_connect_v *       v;
00210 
00211     v = &(m->v.connect);
00212 
00213     iiimp_message_header_print(data_s, m->opcode, -1, -1);
00214 
00215     switch (v->byte_order) {
00216     case IM_CONNECT_BIG_ENDIAN:
00217        (void)fprintf(data_s->print_fp, "\t%s\n", "big endian");
00218        break;
00219     case IM_CONNECT_LITTLE_ENDIAN:
00220        (void)fprintf(data_s->print_fp, "\t%s\n", "little endian");
00221        break;
00222     default:
00223        (void)fprintf(data_s->print_fp, "\t%s\n", "unknown endian");
00224        break;
00225     }
00226 
00227     (void)fprintf(data_s->print_fp, "\tprotocol_version = 0x%02x\n",
00228                 v->protocol_version);
00229 
00230     (void)fprintf(data_s->print_fp, "\tuser name = ");
00231     iiimp_string_print(data_s, v->user_name);
00232     (void)fputc('\n', data_s->print_fp);
00233 
00234     (void)fprintf(data_s->print_fp, "\tauth protocol name = ");
00235     iiimp_string_list_print(data_s, v->auth);
00236     (void)fputc('\n', data_s->print_fp);
00237 }
00238 
00239 
00240 /* Local Variables: */
00241 /* c-file-style: "iiim-project" */
00242 /* End: */