Skip to content

Instantly share code, notes, and snippets.

@fukusaka
Created April 18, 2010 18:41
Show Gist options
  • Save fukusaka/370456 to your computer and use it in GitHub Desktop.
Save fukusaka/370456 to your computer and use it in GitHub Desktop.
diff -uNr unfs3-0.9.20/nfs.c unfs3-0.9.20.utf8mac/nfs.c
--- unfs3-0.9.20/nfs.c 2007-12-06 04:20:43.000000000 +0900
+++ unfs3-0.9.20.utf8mac/nfs.c 2008-03-05 17:05:34.000000000 +0900
@@ -49,6 +49,8 @@
#include "Config/exports.h"
#include "Extras/cluster.h"
+#include "path_conv.h"
+
/*
* decompose filehandle and switch user if permitted access
* otherwise zero result structure and return with error status
@@ -79,6 +81,7 @@
nfsstat3 cat_name(const char *path, const char *name, char *result)
{
char *last;
+ char cooked[NFS_MAXPATHLEN];
if (!path)
return NFS3ERR_STALE;
@@ -89,6 +92,10 @@
if (name[0] == 0 || strchr(name, '/') != NULL)
return NFS3ERR_ACCES;
+ if (!path_from_utf8mac(name, cooked, NFS_MAXPATHLEN))
+ return NFS3ERR_ACCES;
+ name = cooked;
+
if (strlen(path) + strlen(name) + 2 > NFS_MAXPATHLEN)
return NFS3ERR_NAMETOOLONG;
@@ -630,6 +637,7 @@
char obj[NFS_MAXPATHLEN];
int res;
mode_t new_mode;
+ char cooked[NFS_MAXPATHLEN];
PREP(path, argp->where.dir);
pre = get_pre_cached();
@@ -650,7 +658,11 @@
if (result.status == NFS3_OK) {
umask(~new_mode);
- res = backend_symlink(argp->symlink.symlink_data, obj);
+ if (path_from_utf8mac(argp->symlink.symlink_data, cooked, NFS_MAXPATHLEN)) {
+ result.status = NFS3ERR_ACCES;
+ goto step;
+ }
+ res = backend_symlink(cooked, obj);
umask(0);
if (res == -1)
result.status = symlink_err();
@@ -661,6 +673,7 @@
get_post_cached(rqstp);
}
}
+step:
post = get_post_attr(path, argp->where.dir, rqstp);
diff -uNr unfs3-0.9.20/path_conv.c unfs3-0.9.20.utf8mac/path_conv.c
--- unfs3-0.9.20/path_conv.c 1970-01-01 09:00:00.000000000 +0900
+++ unfs3-0.9.20.utf8mac/path_conv.c 2008-03-05 17:18:46.000000000 +0900
@@ -0,0 +1,135 @@
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/syslog.h>
+#include <rpc/rpc.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "nfs.h"
+#include "daemon.h"
+#include "path_conv.h"
+
+struct {
+ size_t len[2];
+ const char *str[2];
+} map[] = {
+ /*hirakana*/
+ { { 3, 6 }, { "\xe3\x81\x8c", "\xe3\x81\x8b\xe3\x82\x99" }, }, /* GA */
+ { { 3, 6 }, { "\xe3\x81\x8e", "\xe3\x81\x8d\xe3\x82\x99" }, }, /* GI */
+ { { 3, 6 }, { "\xe3\x81\x90", "\xe3\x81\x8f\xe3\x82\x99" }, }, /* GU */
+ { { 3, 6 }, { "\xe3\x81\x92", "\xe3\x81\x91\xe3\x82\x99" }, }, /* GE */
+ { { 3, 6 }, { "\xe3\x81\x94", "\xe3\x81\x93\xe3\x82\x99" }, }, /* GO */
+
+ { { 3, 6 }, { "\xe3\x81\x96", "\xe3\x81\x95\xe3\x82\x99" }, }, /* ZA */
+ { { 3, 6 }, { "\xe3\x81\x98", "\xe3\x81\x97\xe3\x82\x99" }, }, /* ZI */
+ { { 3, 6 }, { "\xe3\x81\x9a", "\xe3\x81\x99\xe3\x82\x99" }, }, /* ZU */
+ { { 3, 6 }, { "\xe3\x81\x9c", "\xe3\x81\x9b\xe3\x82\x99" }, }, /* ZE */
+ { { 3, 6 }, { "\xe3\x81\x9e", "\xe3\x81\x9d\xe3\x82\x99" }, }, /* ZO */
+
+ { { 3, 6 }, { "\xe3\x81\xa0", "\xe3\x81\x9f\xe3\x82\x99" }, }, /* DA */
+ { { 3, 6 }, { "\xe3\x81\xa2", "\xe3\x81\xa1\xe3\x82\x99" }, }, /* DI */
+ { { 3, 6 }, { "\xe3\x81\xa5", "\xe3\x81\xa4\xe3\x82\x99" }, }, /* DU */
+ { { 3, 6 }, { "\xe3\x81\xa7", "\xe3\x81\xa6\xe3\x82\x99" }, }, /* DE */
+ { { 3, 6 }, { "\xe3\x81\xa9", "\xe3\x81\xa8\xe3\x82\x99" }, }, /* DO */
+
+ { { 3, 6 }, { "\xe3\x81\xb0", "\xe3\x81\xaf\xe3\x82\x99" }, }, /* BA */
+ { { 3, 6 }, { "\xe3\x81\xb3", "\xe3\x81\xb2\xe3\x82\x99" }, }, /* BI */
+ { { 3, 6 }, { "\xe3\x81\xb6", "\xe3\x81\xb5\xe3\x82\x99" }, }, /* BU */
+ { { 3, 6 }, { "\xe3\x81\xb9", "\xe3\x81\xb8\xe3\x82\x99" }, }, /* BE */
+ { { 3, 6 }, { "\xe3\x81\xbc", "\xe3\x81\xbb\xe3\x82\x99" }, }, /* BO */
+
+ { { 3, 6 }, { "\xe3\x81\xb1", "\xe3\x81\xaf\xe3\x82\x9a" }, }, /* PA */
+ { { 3, 6 }, { "\xe3\x81\xb4", "\xe3\x81\xb2\xe3\x82\x9a" }, }, /* PI */
+ { { 3, 6 }, { "\xe3\x81\xb7", "\xe3\x81\xb5\xe3\x82\x9a" }, }, /* PU */
+ { { 3, 6 }, { "\xe3\x81\xba", "\xe3\x81\xb8\xe3\x82\x9a" }, }, /* PE */
+ { { 3, 6 }, { "\xe3\x81\xbd", "\xe3\x81\xbb\xe3\x82\x9a" }, }, /* PO */
+
+ /*Katakana*/
+ { { 3, 6 }, { "\xe3\x82\xac", "\xe3\x82\xab\xe3\x82\x99" }, }, /* GA */
+ { { 3, 6 }, { "\xe3\x82\xae", "\xe3\x82\xad\xe3\x82\x99" }, }, /* GI */
+ { { 3, 6 }, { "\xe3\x82\xb0", "\xe3\x82\xaf\xe3\x82\x99" }, }, /* GU */
+ { { 3, 6 }, { "\xe3\x82\xb2", "\xe3\x82\xb1\xe3\x82\x99" }, }, /* GE */
+ { { 3, 6 }, { "\xe3\x82\xb4", "\xe3\x82\xb3\xe3\x82\x99" }, }, /* GO */
+
+ { { 3, 6 }, { "\xe3\x82\xb6", "\xe3\x82\xb5\xe3\x82\x99" }, }, /* ZA */
+ { { 3, 6 }, { "\xe3\x82\xb8", "\xe3\x82\xb7\xe3\x82\x99" }, }, /* ZI */
+ { { 3, 6 }, { "\xe3\x82\xba", "\xe3\x82\xb9\xe3\x82\x99" }, }, /* ZU */
+ { { 3, 6 }, { "\xe3\x82\xbc", "\xe3\x82\xbb\xe3\x82\x99" }, }, /* ZE */
+ { { 3, 6 }, { "\xe3\x82\xbe", "\xe3\x82\xbd\xe3\x82\x99" }, }, /* ZO */
+
+ { { 3, 6 }, { "\xe3\x83\x80", "\xe3\x82\xbf\xe3\x82\x99" }, }, /* DA */
+ { { 3, 6 }, { "\xe3\x83\x82", "\xe3\x83\x81\xe3\x82\x99" }, }, /* DI */
+ { { 3, 6 }, { "\xe3\x83\x85", "\xe3\x83\x84\xe3\x82\x99" }, }, /* DU */
+ { { 3, 6 }, { "\xe3\x83\x87", "\xe3\x83\x86\xe3\x82\x99" }, }, /* DE */
+ { { 3, 6 }, { "\xe3\x83\x89", "\xe3\x83\x88\xe3\x82\x99" }, }, /* DO */
+
+ { { 3, 6 }, { "\xe3\x83\x90", "\xe3\x83\x8f\xe3\x82\x99" }, }, /* BA */
+ { { 3, 6 }, { "\xe3\x83\x93", "\xe3\x83\x92\xe3\x82\x99" }, }, /* BI */
+ { { 3, 6 }, { "\xe3\x83\x96", "\xe3\x83\x95\xe3\x82\x99" }, }, /* BU */
+ { { 3, 6 }, { "\xe3\x83\x99", "\xe3\x83\x98\xe3\x82\x99" }, }, /* BE */
+ { { 3, 6 }, { "\xe3\x83\x9c", "\xe3\x83\x9b\xe3\x82\x99" }, }, /* BO */
+
+ { { 3, 6 }, { "\xe3\x83\x91", "\xe3\x83\x8f\xe3\x82\x9a" }, }, /* PA */
+ { { 3, 6 }, { "\xe3\x83\x94", "\xe3\x83\x92\xe3\x82\x9a" }, }, /* PI */
+ { { 3, 6 }, { "\xe3\x83\x97", "\xe3\x83\x95\xe3\x82\x9a" }, }, /* PU */
+ { { 3, 6 }, { "\xe3\x83\x9a", "\xe3\x83\x98\xe3\x82\x9a" }, }, /* PE */
+ { { 3, 6 }, { "\xe3\x83\x9d", "\xe3\x83\x9b\xe3\x82\x9a" }, }, /* PO */
+};
+#define mapsize (sizeof(map)/sizeof(map[0]))
+
+enum { TOUTF8MAC, FROMUTF8MAC };
+
+static int
+path_convert_utf8mac(int direct, const char _s1[], char _s2[], size_t limit)
+{
+ size_t i, src, dst, p1, p2;
+ const unsigned char *s1 = (const unsigned char *)_s1;
+ unsigned char *s2 = (unsigned char *)_s2;
+
+ switch (direct) {
+ case TOUTF8MAC: src = 0; dst = 1; break;
+ case FROMUTF8MAC: src = 1; dst = 0; break;
+ default: return 0;
+ }
+
+ p1 = p2 = 0;
+ while (s1[p1] != 0 && p2 + 1 < limit) {
+ if (s1[p1] == 0xe3) {
+ for (i = 0; i < mapsize; i++)
+ if (memcmp(&s1[p1], map[i].str[src], map[i].len[src]) == 0)
+ break;
+ if (i != mapsize) {
+ memcpy(&s2[p2], map[i].str[dst], map[i].len[dst]);
+ p1 += map[i].len[src];
+ p2 += map[i].len[dst];
+ continue;
+ }
+ }
+ s2[p2++] = s1[p1++];
+ }
+ s2[p2] = 0;
+
+ return 1;
+}
+
+int
+path_to_utf8mac(const char orig[], char cooked[], size_t limit)
+{
+ //logmsg(LOG_INFO, "to orig name: %s", orig);
+
+ return path_convert_utf8mac(TOUTF8MAC, orig, cooked, limit);
+}
+
+int
+path_from_utf8mac(const char orig[], char cooked[], size_t limit)
+{
+ //logmsg(LOG_INFO, "from orig name: %s", orig);
+
+ return path_convert_utf8mac(FROMUTF8MAC, orig, cooked, limit);
+}
diff -uNr unfs3-0.9.20/path_conv.h unfs3-0.9.20.utf8mac/path_conv.h
--- unfs3-0.9.20/path_conv.h 1970-01-01 09:00:00.000000000 +0900
+++ unfs3-0.9.20.utf8mac/path_conv.h 2008-03-05 16:50:57.000000000 +0900
@@ -0,0 +1,7 @@
+#ifndef PATH_CONV_H
+#define PATH_CONV_H
+
+int path_to_utf8mac(const char orig[], char cooked[], size_t limit);
+int path_from_utf8mac(const char orig[], char cooked[], size_t limit);
+
+#endif /* PATH_CONV_H */
diff -uNr unfs3-0.9.20/readdir.c unfs3-0.9.20.utf8mac/readdir.c
--- unfs3-0.9.20/readdir.c 2007-01-06 00:08:12.000000000 +0900
+++ unfs3-0.9.20.utf8mac/readdir.c 2008-03-05 16:57:23.000000000 +0900
@@ -25,6 +25,8 @@
#include "Config/exports.h"
#include "error.h"
+#include "path_conv.h"
+
/*
* maximum number of entries in readdir results
*
@@ -91,6 +93,7 @@
count3 i, real_count;
static char obj[NFS_MAXPATHLEN * MAX_ENTRIES];
char scratch[NFS_MAXPATHLEN];
+ char cooked[NFS_MAXPATHLEN];
/* we refuse to return more than 4k from READDIR */
if (count > 4096)
@@ -140,7 +143,8 @@
if (i > 0)
entry[i - 1].nextentry = &entry[i];
- if (strlen(path) + strlen(this->d_name) + 1 < NFS_MAXPATHLEN) {
+ if (path_to_utf8mac(this->d_name, cooked, NFS_MAXPATHLEN)
+ && (strlen(path) + strlen(this->d_name) + 1 < NFS_MAXPATHLEN)) {
if (strcmp(path, "/") == 0)
sprintf(scratch, "/%s", this->d_name);
@@ -154,7 +158,7 @@
return result;
}
- strcpy(&obj[i * NFS_MAXPATHLEN], this->d_name);
+ strcpy(&obj[i * NFS_MAXPATHLEN], cooked);
entry[i].fileid = buf.st_ino;
entry[i].name = &obj[i * NFS_MAXPATHLEN];
@@ -162,7 +166,7 @@
entry[i].nextentry = NULL;
/* account for entry size */
- real_count += ENTRY_SIZE + NAME_SIZE(this->d_name);
+ real_count += ENTRY_SIZE + NAME_SIZE(cooked);
/* whoops, overflowed the maximum size */
if (real_count > count && i > 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment