📄 kml_decode.c
字号:
/* * 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 + -