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

📄 kml_decode.c

📁 《嵌入式系统设计与实例开发实验教材二源码》Linux内核移植与编译实验
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * KML Decoding * * Copryright (C) 1996 Arthur Ma <arthur.ma@mountainviewdata.com>  * * Copyright (C) 2001 Mountainview Data, Inc. */#define __NO_VERSION__#include <linux/module.h>#include <linux/errno.h>#include <linux/kernel.h>#include <linux/major.h>#include <linux/slab.h>#include <linux/vmalloc.h>#include <linux/mm.h>#include <linux/intermezzo_fs.h>#include <linux/intermezzo_kml.h>static int size_round (int val);static int unpack_create (struct kml_create *rec, char *buf,                                int pos, int *rec_offs);static int unpack_open (struct kml_open *rec, char *buf,                                int pos, int *rec_offs);static int unpack_symlink (struct kml_symlink *rec, char *buf,                                int pos, int *rec_offs);static int unpack_mknod (struct kml_mknod *rec, char *buf,                                int pos, int *rec_offs);static int unpack_link (struct kml_link *rec, char *buf,                                int pos, int *rec_offs);static int unpack_rename (struct kml_rename *rec, char *buf,                                int pos, int *rec_offs);static int unpack_unlink (struct kml_unlink *rec, char *buf,                                int pos, int *rec_offs);static int unpack_rmdir (struct kml_rmdir *rec, char *buf,                                int pos, int *rec_offs);static int unpack_setattr (struct kml_setattr *rec, char *buf,                                int pos, int *rec_offs);static int unpack_close (struct kml_close *rec, char *buf,                                int pos, int *rec_offs);static int unpack_mkdir (struct kml_mkdir *rec, char *buf,                                int pos, int *rec_offs);#if 0static int unpack_endmark (struct kml_endmark *rec, char *buf,                                int pos, int *rec_offs);static void print_kml_endmark (struct kml_endmark *rec);#endifstatic int kml_unpack (char *kml_buf, int rec_size, int kml_offset,                        struct kml_rec **newrec);static char *kml_version (struct presto_version *ver);static void print_kml_prefix (struct big_journal_prefix *head);static void print_kml_create (struct kml_create *rec);static void print_kml_mkdir (struct kml_mkdir *rec);static void print_kml_unlink (struct kml_unlink *rec);static void print_kml_rmdir (struct kml_rmdir *rec);static void print_kml_close (struct kml_close *rec);static void print_kml_symlink (struct kml_symlink *rec);static void print_kml_rename (struct kml_rename *rec);static void print_kml_setattr (struct kml_setattr *rec);static void print_kml_link (struct kml_link *rec);static void print_kml_mknod (struct kml_mknod *rec);static void print_kml_open (struct kml_open *rec);static void print_kml_suffix (struct journal_suffix *tail);static char *readrec (char *recbuf, int reclen, int pos, int *size);#define  KML_PREFIX_WORDS           8static int kml_unpack (char *kml_buf, int rec_size, int kml_offset,                         struct kml_rec **newrec){        struct kml_rec  *rec;        char            *p;        int             pos, rec_offs;        int             error;        ENTRY;        if (rec_size < sizeof (struct journal_prefix) +                       sizeof (struct journal_suffix))                return -EBADF;        PRESTO_ALLOC(rec, struct kml_rec *, sizeof (struct kml_rec));        if (rec == NULL) {                EXIT;                return -ENOMEM;        }        rec->rec_kml_offset = kml_offset;        rec->rec_size = rec_size;        p = kml_buf;        p = dlogit (&rec->rec_head, p, KML_PREFIX_WORDS * sizeof (int));        p = dlogit (&rec->rec_head.groups, p,                         sizeof (int) * rec->rec_head.ngroups);        pos = sizeof (struct journal_prefix) +                         sizeof (int) * rec->rec_head.ngroups;        switch (rec->rec_head.opcode)        {                case KML_CREATE:                        error = unpack_create (&rec->rec_kml.create,                                         kml_buf, pos, &rec_offs);                        break;                case KML_MKDIR:                        error = unpack_mkdir (&rec->rec_kml.mkdir,                                         kml_buf, pos, &rec_offs);                        break;                case KML_UNLINK:                        error = unpack_unlink (&rec->rec_kml.unlink,                                         kml_buf, pos, &rec_offs);                        break;                case KML_RMDIR:                        error = unpack_rmdir (&rec->rec_kml.rmdir,                                         kml_buf, pos, &rec_offs);                        break;                case KML_CLOSE:                        error = unpack_close (&rec->rec_kml.close,                                         kml_buf, pos, &rec_offs);                        break;                case KML_SYMLINK:                        error = unpack_symlink (&rec->rec_kml.symlink,                                         kml_buf, pos, &rec_offs);                        break;                case KML_RENAME:                        error = unpack_rename (&rec->rec_kml.rename,                                         kml_buf, pos, &rec_offs);                        break;                case KML_SETATTR:                        error = unpack_setattr (&rec->rec_kml.setattr,                                         kml_buf, pos, &rec_offs);                        break;                case KML_LINK:                        error = unpack_link (&rec->rec_kml.link,                                         kml_buf, pos, &rec_offs);                        break;                case KML_OPEN:                        error = unpack_open (&rec->rec_kml.open,                                         kml_buf, pos, &rec_offs);                        break;                case KML_MKNOD:                        error = unpack_mknod (&rec->rec_kml.mknod,                                         kml_buf, pos, &rec_offs);                        break;#if 0                case KML_ENDMARK:                        error = unpack_endmark (&rec->rec_kml.endmark,                                         kml_buf, pos, &rec_offs);                        break;#endif                default:                        CDEBUG (D_KML, "wrong opcode::%u\n",                                         rec->rec_head.opcode);                        EXIT;                        return -EINVAL;        }         if (error) {                PRESTO_FREE (rec, sizeof (struct kml_rec));                return -EINVAL;        }        p = kml_buf + rec_offs;        p = dlogit (&rec->rec_tail, p, sizeof (struct journal_suffix));        memset (&rec->kml_optimize, 0, sizeof (struct kml_optimize));        *newrec = rec;        EXIT;        return 0;}static int size_round (int val){        return (val + 3) & (~0x3);}static int unpack_create (struct kml_create *rec, char *buf,                                 int pos, int *rec_offs){        char *p, *q;        int unpack_size = 88;        int pathlen;        ENTRY;        p = buf + pos;        p = dlogit (&rec->old_parentv, p, sizeof (struct presto_version));        p = dlogit (&rec->new_parentv, p, sizeof (struct presto_version));        p = dlogit (&rec->new_objectv, p, sizeof (struct presto_version));        p = dlogit (&rec->mode, p, sizeof (int));        p = dlogit (&rec->uid, p, sizeof (int));        p = dlogit (&rec->gid, p, sizeof (int));        p = dlogit (&pathlen, p, sizeof (int));        PRESTO_ALLOC(q, char *, pathlen + 1);        if (q == NULL) {                EXIT;                return -ENOMEM;        }        memcpy (q, p, pathlen);        q[pathlen] = '\0';        rec->path = q;        *rec_offs = pos + unpack_size + size_round(pathlen);        EXIT;        return 0;}static int unpack_open (struct kml_open *rec, char *buf,                                 int pos, int *rec_offs){        *rec_offs = pos;        return 0;}static int unpack_symlink (struct kml_symlink *rec, char *buf,                                 int pos, int *rec_offs){        char *p, *q;        int unpack_size = 88;        int pathlen, targetlen;        ENTRY;        p = buf + pos;        p = dlogit (&rec->old_parentv, p, sizeof (struct presto_version));        p = dlogit (&rec->new_parentv, p, sizeof (struct presto_version));        p = dlogit (&rec->new_objectv, p, sizeof (struct presto_version));        p = dlogit (&rec->uid, p, sizeof (int));        p = dlogit (&rec->gid, p, sizeof (int));        p = dlogit (&pathlen, p, sizeof (int));        p = dlogit (&targetlen, p, sizeof (int));        PRESTO_ALLOC(q, char *, pathlen + 1);        if (q == NULL) {                EXIT;                return -ENOMEM;        }        memcpy (q, p, pathlen);        q[pathlen] = '\0';        rec->sourcepath = q;        PRESTO_ALLOC(q, char *, targetlen + 1);        if (q == NULL) {                PRESTO_FREE (rec->sourcepath, pathlen + 1);                EXIT;                return -ENOMEM;        }        memcpy (q, p, targetlen);        q[targetlen] = '\0';        rec->targetpath = q;        *rec_offs = pos + unpack_size + size_round(pathlen) +                        size_round(targetlen);        EXIT;        return 0;}static int unpack_mknod (struct kml_mknod *rec, char *buf,                                 int pos, int *rec_offs){        char *p, *q;        int unpack_size = 96;        int pathlen;        ENTRY;        p = buf + pos;        p = dlogit (&rec->old_parentv, p, sizeof (struct presto_version));        p = dlogit (&rec->new_parentv, p, sizeof (struct presto_version));        p = dlogit (&rec->new_objectv, p, sizeof (struct presto_version));        p = dlogit (&rec->mode, p, sizeof (int));        p = dlogit (&rec->uid, p, sizeof (int));        p = dlogit (&rec->gid, p, sizeof (int));        p = dlogit (&rec->major, p, sizeof (int));        p = dlogit (&rec->minor, p, sizeof (int));        p = dlogit (&pathlen, p, sizeof (int));        PRESTO_ALLOC(q, char *, pathlen + 1);        if (q == NULL) {                EXIT;                return -ENOMEM;        }        memcpy (q, p, pathlen);        q[pathlen] = '\0';        rec->path = q;        *rec_offs = pos + unpack_size + size_round(pathlen);        EXIT;        return 0;}static int unpack_link (struct kml_link *rec, char *buf,                                 int pos, int *rec_offs){        char *p, *q;        int unpack_size = 80;        int pathlen, targetlen;        ENTRY;        p = buf + pos;        p = dlogit (&rec->old_parentv, p, sizeof (struct presto_version));        p = dlogit (&rec->new_parentv, p, sizeof (struct presto_version));        p = dlogit (&rec->new_objectv, p, sizeof (struct presto_version));        p = dlogit (&pathlen, p, sizeof (int));        p = dlogit (&targetlen, p, sizeof (int));        PRESTO_ALLOC(q, char *, pathlen + 1);        if (q == NULL) {                EXIT;                return -ENOMEM;        }        memcpy (q, p, pathlen);        q[pathlen] = '\0';        rec->sourcepath = q;        p += size_round (pathlen);        PRESTO_ALLOC(q, char *, targetlen + 1);        if (q == NULL) {                PRESTO_FREE (rec->sourcepath, pathlen + 1);                EXIT;                return -ENOMEM;        }        memcpy (q, p, targetlen);        q[targetlen] = '\0';        rec->targetpath = q;        *rec_offs = pos + unpack_size + size_round(pathlen) +                        size_round(targetlen);        EXIT;        return 0;}static int unpack_rename (struct kml_rename *rec, char *buf,                                 int pos, int *rec_offs){        char *p, *q;        int unpack_size = 104;        int pathlen, targetlen;        ENTRY;        p = buf + pos;        p = dlogit (&rec->old_objectv, p, sizeof (struct presto_version));        p = dlogit (&rec->new_objectv, p, sizeof (struct presto_version));        p = dlogit (&rec->new_tgtv, p, sizeof (struct presto_version));

⌨️ 快捷键说明

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