Back to index

im-sdk  12.3.91
iiimp-print.c
Go to the documentation of this file.
00001 #include <locale.h>
00002 #include <stdio.h>
00003 #include <unistd.h>
00004 #include <stdlib.h>
00005 #include <string.h>
00006 #include <errno.h>
00007 #include <fcntl.h>
00008 
00009 #include <iiimp.h>
00010 #include "iiimp-opcode.h"
00011 
00012 #define       IO_READ              (0xfe)
00013 #define       IO_WRITE      (0xef)
00014 #define MAGIC        "IIIMP DUMP DATA"
00015 #define       DATA_VERSION  (1)
00016 #define BIG_ENDIAN   (1)
00017 #define SMALL_ENDIAN (2)
00018 
00019 
00020 typedef enum {
00021        unknown_endian = 0,
00022        big_endian = 1,
00023        little_endian = 2,
00024 } endian_t;
00025 
00026 typedef struct {
00027        char          fds;
00028        int           r_seq_no;
00029        int           w_seq_no;
00030        int           r_left;
00031        int           w_left;
00032        char          r_op;
00033        char          w_op;
00034        unsigned char *      buf;
00035        off_t         buf_off;
00036        size_t        buf_size;
00037        endian_t      byte_order;
00038        int           protocol_version;
00039        IIIMP_data_s *       data_s;
00040 } client_t;
00041 
00042 static client_t      client[1024];
00043 
00044 uint_t        print_flag;
00045 int           abort_on_error;
00046 int           follow;
00047 int           partial;
00048 int           dump_fd = -1;
00049 int           input_fd;
00050 
00051 #define       UINTEGER32(a, e)     ((BIG_ENDIAN == (e)) ?                    \
00052                              ((*(((unsigned char *)(a)) + 0) << 24) + \
00053                               (*(((unsigned char *)(a)) + 1) << 16) + \
00054                               (*(((unsigned char *)(a)) + 2) << 8)  + \
00055                               (*(((unsigned char *)(a)) + 3) << 0)) : \
00056                              ((*(((unsigned char *)(a)) + 3) << 24) + \
00057                               (*(((unsigned char *)(a)) + 2) << 16) + \
00058                               (*(((unsigned char *)(a)) + 1) << 8)  + \
00059                               (*(((unsigned char *)(a)) + 0) << 0)))
00060 
00061 
00062 #define       INTEGER16(a, f)      ((big_endian == client[f].byte_order) ? \
00063                       ((*((unsigned char *)(a)) << 8) +  \
00064                        *(((unsigned char *)(a)) + 1)) : \
00065                       ((*(((unsigned char *)(a)) + 1) << 8) + \
00066                        *((unsigned char *)(a))))
00067 
00068 #define       INTEGER32(a, f)      ((big_endian == client[f].byte_order) ? \
00069                       ((*(((unsigned char *)(a)) + 0) << 24) +  \
00070                        (*(((unsigned char *)(a)) + 1) << 16) + \
00071                        (*(((unsigned char *)(a)) + 2) << 8) + \
00072                        (*(((unsigned char *)(a)) + 3) << 0)) : \
00073                       ((*(((unsigned char *)(a)) + 3) << 24) +  \
00074                        (*(((unsigned char *)(a)) + 2) << 16) + \
00075                        (*(((unsigned char *)(a)) + 1) << 8) + \
00076                        (*(((unsigned char *)(a)) + 0) << 0)))
00077 
00078 static void   dump(int thread_id, int io_type, int fildes,
00079                    const unsigned char * buf, size_t nbyte);
00080 
00081 
00082 void
00083 buf_free_all()
00084 {
00085        int    i;
00086        for (i = 0; i < 1024; i++) {
00087               if (NULL != client[i].buf) {
00088                      free(client[i].buf);
00089               }
00090        }
00091        return;
00092 }
00093 
00094 
00095 void
00096 dump(int thread_id, int io_type, int fildes, const unsigned char * buf, size_t nbyte)
00097 {
00098        const unsigned char *       p;
00099        size_t               rest;
00100        IIIMP_message *             m;
00101        const unsigned char *       p0;
00102        size_t               rest0;
00103 
00104        p = buf;
00105 
00106        if (0 == nbyte) {
00107               fprintf(stdout, "%d:%d -- connection closed\n", thread_id, fildes);
00108               iiimp_data_s_delete(client[fildes].data_s);
00109               free(client[fildes].buf);
00110               memset(&(client[fildes]), 0, sizeof (client[fildes]));
00111               return;
00112        }
00113 
00114        if (NULL == client[fildes].buf) {
00115               client[fildes].buf_size = (2 * 1024 * 1024);
00116               client[fildes].buf = malloc(2 * 1024 * 1024);
00117               client[fildes].data_s = iiimp_data_s_new();
00118        }
00119        memcpy(client[fildes].buf + client[fildes].buf_off, buf, nbyte);
00120        client[fildes].buf_off += nbyte;
00121        client[fildes].w_seq_no += 1;
00122 
00123        if ((0 == client[fildes].w_left) && (4 <= client[fildes].buf_off)) {
00124               p = client[fildes].buf;
00125 
00126               client[fildes].w_op = (0x7f & *p);
00127               client[fildes].w_seq_no = 0;
00128               client[fildes].w_left = (((*(p + 1) << 16) +
00129                                      (*(p + 2) << 8) +
00130                                      (*(p + 3) << 0)) * 4);
00131               client[fildes].w_left += 4;
00132        }
00133 
00134        if (client[fildes].w_left != client[fildes].buf_off) {
00135               if (partial <= client[fildes].buf_off) {
00136                      fprintf(stdout, "%d:%d", thread_id, fildes);
00137                      if (IO_READ == io_type) {
00138                             fprintf(stdout, "<-");
00139                      } else {
00140                             fprintf(stdout, "->");
00141                      }
00142                      fprintf(stdout, " partial +%d = %d / %d\n",
00143                             nbyte, client[fildes].buf_off, client[fildes].w_left);
00144               }
00145               return;
00146        }
00147 
00148        p = client[fildes].buf;
00149 
00150        fprintf(stdout, "%d:%d", thread_id, fildes);
00151        if (IO_READ == io_type) {
00152               fprintf(stdout, "<-");
00153        } else {
00154               fprintf(stdout, "->");
00155        }
00156        p0 = p + 4;
00157        rest0 = (client[fildes].w_left - 4);
00158 
00159        m = iiimp_message_unpack(client[fildes].data_s,
00160                              client[fildes].w_op, &rest0, &p0);
00161        if (NULL != m) {
00162               iiimp_message_print(client[fildes].data_s, m);
00163               iiimp_message_delete(client[fildes].data_s, m);
00164        } else if (0 != abort_on_error) {
00165               p0 = p + 4;
00166               rest0 = (client[fildes].w_left - 4);
00167               m = iiimp_message_unpack(client[fildes].data_s,
00168                                     client[fildes].w_op, &rest0, &p0);
00169               abort();
00170        }
00171 
00172        client[fildes].buf_off = 0;
00173        client[fildes].w_left = 0;
00174        client[fildes].w_seq_no = 0;
00175 
00176        return;
00177 }
00178 
00179 
00180 int
00181 pad_size(int nbyte)
00182 {
00183        int    i;
00184 
00185        i = (nbyte % 16);
00186        return ((0 == i) ? 0 : (16 - i));
00187 }
00188 
00189 
00190 void
00191 usage()
00192 {
00193        fprintf(stderr, "%s [-a] [-j] [-f] [-p nbyte] [iiim-data-file]\n", "iiim-printer2");
00194 }
00195 
00196 
00197 void
00198 parse_opt(int argc, char ** argv)
00199 {
00200        int           c;
00201        extern char * optarg;
00202        extern int    optind;
00203        extern int    opterr;
00204        extern int    optopt;
00205 
00206        print_flag = 0;
00207        abort_on_error = 0;
00208        follow = 0;
00209        partial = 8;
00210 
00211        while (EOF != (c = getopt(argc, argv, "ajfd:p:"))) {
00212               switch (c) {
00213               case 'a':
00214                      abort_on_error = 1;
00215                      break;
00216               case 'j':
00217                      print_flag |= IIIMP_PRINT_JARFILE;
00218                      break;
00219               case 'f':
00220                      follow = 1;
00221                      break;
00222               case 'd':
00223                      dump_fd = atol(optarg);
00224                      break;
00225               case 'p':
00226                      partial = atol(optarg);
00227                      break;
00228               default:
00229                      usage(c);
00230                      exit(1);
00231                      break;
00232               }
00233        }
00234        if (optind == argc) {
00235               input_fd = 0;
00236        } else {
00237               input_fd = open(*(argv + optind), O_RDONLY, 0);
00238               if (-1 == input_fd) {
00239                      perror("open");
00240                      exit(1);
00241               }
00242        }
00243 }
00244 
00245 int
00246 main(int argc, char ** argv)
00247 {
00248        char          header[256];
00249        char          buf[1024 * 1024];
00250        char *        p;
00251        int           i;
00252        int           r;
00253        int           pad;
00254        uint32_t      thread_id;
00255        uint32_t      fildes;
00256        uint32_t      io_type;
00257        uint32_t      data_size;
00258        uint32_t      byte_order;
00259        uint32_t      version;
00260 
00261        setlocale(LC_ALL, "");
00262 
00263        parse_opt(argc, argv);
00264 
00265        r = read(input_fd, header, 32);
00266        if (r < 0) {
00267               perror("read");
00268               exit(1);
00269        }
00270        if (32 != r) {
00271               fprintf(stderr, "initial read error\n");
00272               exit(1);
00273        }
00274 
00275        if (0 != memcmp(header, MAGIC, 16)) {
00276               fprintf(stderr, "not IIIMP data\n");
00277               exit(1);
00278        }
00279 
00280        byte_order = ((1 == header[16]) ? SMALL_ENDIAN : BIG_ENDIAN);
00281        p = (header + 16 + 4);
00282        version = UINTEGER32(p, byte_order);
00283 
00284        for (;;) {
00285               for (i = 0; i < 16;) {
00286                      r = read(input_fd, header + i, 16 - i);
00287                      if (r < 0) {
00288                             perror("read");
00289                             exit(1);
00290                      }
00291                      if (0 == r) {
00292                             if (0 == follow) {
00293                                    buf_free_all();
00294                                    exit(0);
00295                             }
00296                             sleep(1);
00297                             continue;
00298                      }
00299                      i += r;
00300               }
00301               p = header;
00302               thread_id = UINTEGER32(p, byte_order);
00303               p += 4;
00304               io_type = UINTEGER32(p, byte_order);
00305               p += 4;
00306               fildes = UINTEGER32(p, byte_order);
00307               p += 4;
00308               data_size = UINTEGER32(p, byte_order);
00309               if ((sizeof (buf)) < data_size) {
00310                      fprintf(stderr, "too large data size %u\n", data_size);
00311                      exit(1);
00312               }
00313 
00314               pad = pad_size(data_size);
00315 
00316               data_size += pad;
00317 
00318               for (i = 0; i < data_size;) {
00319                      r = read(input_fd, buf + i, data_size - i);
00320                      if (r < 0) {
00321                             perror("read");
00322                             exit(1);
00323                      }
00324                      if (0 == r) {
00325                             if (0 == follow) {
00326                                    buf_free_all();
00327                                    exit(0);
00328                             }
00329                             sleep(1);
00330                             continue;
00331                      }
00332                      i += r;
00333               }
00334 
00335               if ((dump_fd < 0) || (dump_fd == fildes)) {
00336                      dump(thread_id, io_type, fildes,
00337                           (unsigned const char *)buf, data_size - pad);
00338               }
00339        }
00340 
00341        return 0;
00342 }