便便代码人生

关注技术, 偶尔动动手

Archive for the 'C/C++' Category

C/C++

[原]涂鸦板oekakibbs和Shi-PainterPRO数据格式分析

Posted by bianbian on 2006-12-19 06:33


本文Tags: ,

去年用C语言实现的涂鸦板:http://bbs.nju.edu.cn/pntmain
想当年,一夜没睡,不停地debug、截获网络数据,分析涂鸦板oekakibbs和Shi-PainterPRO的数据格式。
最后保存成功带给我的喜悦我是终身难忘。这也是我喜欢编程的部分原因吧。呵呵
oekakibbs和Shi-PainterPRO是比较有名的涂鸦板程序(实际是Java Applet程序),通过http协议和自定义的数据格式往后台提交数据。解析数据网络上比较多的是php和asp的代码,但是因为和彼此自己的系统结合,所以看起来比较费尽。不过从来没有数据格式说明文档。
今天偶然又翻了一下这些代码,顺便在blog里记一下。要是能给其他人省点力气,也算功德一件。呵呵

  1. /*
  2. 解析涂鸦板传过来的数据并保存图片
  3. Net@Lilybbs, 2005-11-14 7:18
  4. /////////////////////////////
  5. 参数传递:pntupload?临时key_工具名
  6. ====================================
  7. oekakibbs数据格式:
  8. -------------------------------
  9. ...Content-type:string
  10.  
  11. Content-type:string
  12.  
  13. Content-type:image/0
  14.  
  15. {PNG图片数据}
  16. Content-type:animation/
  17.  
  18. {oekakibbs动画数据}
  19. ====================================
  20. Shi-PainterPRO数据格式:
  21. -------------------------------
  22. S0000000000{当前PNG图片的字节数}
  23. {PNG图片数据}{pch长度}{pch文件内容}
  24. -------------------------------
  25. //以下是pch文件内容:
  26. layer_count=3
  27. layer_max=35
  28. layer_last=35
  29. image_width=300
  30. image_height=300
  31. count_lines=25
  32. quality=1
  33.  
  34. {其他信息}
  35. -------------------------------
  36. */
  37. #include "www.h"
  38.  
  39. int pntupload_main()
  40. {
  41.     int n, i, j, key=0;
  42.     char tmp[80], *buf, tool[30], *p;
  43.     FILE *fp;
  44.  
  45.     chdir(BBSHOME);
  46.     http_header(200);
  47.     printf("Content-type: text/html; charset=gb2312\n\n");
  48.     n = atoi(getsenv("CONTENT_LENGTH"));
  49.     if (n<0 || n>3000000)
  50.         http_fatal("too big");
  51.     buf = malloc(n);
  52.     if(buf==0) http_fatal("out of memory");
  53.     fread(buf, 1, n, stdin); //读入buf
  54. /*
  55.     fp = fopen("paint/data", "w");
  56.     fwrite(buf, 1, n, fp);
  57.     fclose(fp);
  58. */
  59.     //-------- 获得_U_KEY
  60.     key = atoi(getsenv("QUERY_STRING"));
  61.     //-------- 获得tool
  62.     p = strchr(getsenv("QUERY_STRING"), '_');
  63.     strsncpy(tool, p+1, 20);
  64.  
  65.     //-------- 根据不同tool, 不同处理数据
  66.     //oekakibbs和oekakibbs2的处理是一样的
  67.     if(!strncmp("oekakibbs", tool, 9))
  68.     {
  69.         //-------- 获得图片
  70.         i = memstr(buf, n, "Content-type:image/0");
  71.         j = memstr(buf+i+24, n, "Content-type:animation/"); //24是"Content-type:image/0\r\n\r\n"的长度
  72.         sprintf(tmp, "paint/tmp/%d.png", key);
  73.         fp = fopen(tmp, "w");
  74.         fwrite(buf + i + 24, 1, j, fp); //j实际是png的长度
  75.         fclose(fp);
  76.         //-------- 获得动画
  77.         j += i+24; //j现在是从buf开始指向Content-type:animation的偏移量
  78.         sprintf(tmp, "paint/tmp/%d.oeb", key);
  79.         fp = fopen(tmp, "w");
  80.         fwrite(buf+j+27, 1, n - j - 27, fp); //p2-buf是长度,27是"Content-type:animation/\r\n\r\n"的长度
  81.         fclose(fp);
  82.         //需要输出success告诉applet保存成功
  83.         printf("success");
  84.     }
  85.     else if(!strcmp("Shi-Painter", tool))
  86.     {
  87.         //png 头:HEX 89 50 4E 47 0D 0A
  88.         //png 尾:HEX 49 45 4E 44 AE 42 60 82
  89.         //unsigned char pngend[] = {0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82};
  90.         i = memstr(buf, n, "\r\n"); //第2行开始就是PNG图片
  91.         j = atoi(buf+1); //buf[0]固定是S,之后就是PNG的长度
  92.         sprintf(tmp, "paint/tmp/%d.png", key);
  93.         fp = fopen(tmp, "w");
  94.         fwrite(buf+i+2, 1, j, fp);
  95.         fclose(fp);
  96.         //-------- 获得动画
  97.         j += i+2; //j现在是从buf开始指向PNG末尾的偏移量
  98.         i = memstr(buf+j, n, "layer_count="); //这里的i就相当于oekakibbs里面的27:就是PNG末尾到layer_count的长度
  99.         sprintf(tmp, "paint/tmp/%d.oeb", key);
  100.         fp = fopen(tmp, "w");
  101.         fwrite(buf+j+i, 1, n-j-i, fp);
  102.         fclose(fp);
  103.     }
  104.     exit(0);
  105. }
标签: ,

遵守创作共用协议,转载请链接形式注明来自http://bianbian.org 做人要厚道

相关日志

Posted in C/C++, Technology | 2 Comments »

[译]JSON的C语言实现: JSON-C – A JSON implementation in C

Posted by bianbian on 2006-12-17 03:44


本文Tags:

[翻译] JSON-C能让你在C语言里轻松创建JSON对象,输出JSON字符串,解析JSON字符串成JSON对象。
test1.c的部分实例代码:

  1. struct json_object *my_array;
  2.   my_array = json_object_new_array();
  3.   json_object_array_add(my_array, json_object_new_int(1));
  4.   json_object_array_add(my_array, json_object_new_int(2));
  5.   json_object_array_add(my_array, json_object_new_int(3));
  6.   json_object_array_put_idx(my_array, 4, json_object_new_int(5));
  7.   printf("my_array=\n");
  8.   for(i=0; i < json_object_array_length(my_array); i++) {
  9.     struct json_object *obj = json_object_array_get_idx(my_array, i);
  10.     printf("\t[%d]=%s\n", i, json_object_to_json_string(obj));
  11.   }
  12.   printf("my_array.to_string()=%s\n", json_object_to_json_string(my_array));

地址: http://oss.metaparadigm.com/json-c/

[Original] JSON-C implements a reference counting object model that allows you to easily construct JSON objects in C, output them as JSON formatted strings and parse JSON formatted strings back into the C representation of JSON objects.

Copyright Metaparadigm Pte. Ltd. 2004, 2005. Michael Clark

如果不清楚JSON,请参考:http://www.json.org

标签:

遵守创作共用协议,转载请链接形式注明来自http://bianbian.org 做人要厚道

相关日志

Posted in C/C++, Technology | 5 Comments »

[原]apache模块的编写实例 (反向透明代理实现方式之一)

Posted by bianbian on 2006-10-30 07:45


本文Tags: , ,

除了用端口映射(当然,要在转发数据包前传递客户端IP地址给内网服务器)来实现反向透明代理以外,利用apache的mod_proxy也是一种办法。而后一种办法更方便的地方是一个80端口可以给很多域名使用(即虚拟主机)——当然前一种也是可以,只要根据不同域名把数据包转发到不同内网服务器而已,我只是懒得写而已;因为工作量显然是直接用apache来得少。。。。
我贴出用后一种办法实现以前lilybbs.net公网代理的代码;之所以要自己写apache的模块,是因为直接用mod_proxy是不能传递客户端的IP地址给真正的内网服务器的。我原本打算是插入自定义的一个HTTP头来实现IP传递,这样一般是没有问题;但是当客户端本身访问网络经过Squid代理时,Squid会删除掉非标准的HTTP头,真是FT。所以我采用的方法是通过”Accept-Language”头传递客户端IP地址,”Accept-Language”是用来标示客户端接受的页面语言顺序(中文?英文?之类),在非国际化的网站中并没有很大的用处。
apache的模块编写其实很简单,大部分都是架子工程,直接贴过来就可以。
代码如下(代码经过lilybbs.net公网访问测试OK,不过现在学校网络中心停止了lilybbs.net的公网出口)。

  1. /*
  2. apache 2.x 模块
  3. 所有http请求的header发送ip,以实现代理
  4. 如需使用 LilybbsipEnable 设为 on 即可(需要和mod_proxy一起使用)
  5.  
  6. 编译:
  7. /home/apache2/bin/apxs -i -a -c mod_lilybbsip.c
  8.  
  9. 参考:
  10. http://modules.apache.org/
  11.  
  12. 作者:
  13. Net@Lilybbs, 2006-3-26 17:38
  14. http://bianbian.org
  15. */
  16.  
  17. #include "httpd.h"
  18. #include "http_config.h"
  19. #include "http_core.h"
  20. #include "http_log.h"
  21. #include "http_protocol.h"
  22. #include "http_vhost.h"
  23. #include "apr_strings.h"
  24.  
  25. module AP_MODULE_DECLARE_DATA lilybbsip_module;
  26.  
  27.  
  28. typedef struct {
  29.     int enable;
  30. } lilybbsip_server_cfg;
  31.  
  32. static void *lilybbsip_create_server_cfg(apr_pool_t *p, server_rec *s) {
  33.     lilybbsip_server_cfg *cfg = (lilybbsip_server_cfg *)apr_pcalloc(p, sizeof(lilybbsip_server_cfg));
  34.     if (!cfg)
  35.         return NULL;
  36.  
  37.     cfg->enable = 0;
  38.  
  39.     return (void *)cfg;
  40. }
  41.  
  42.  
  43. static const char *lilybbsip_enable(cmd_parms *cmd, void *dummy, int flag) {
  44.     lilybbsip_server_cfg *cfg = (lilybbsip_server_cfg *)ap_get_module_config(cmd->server->module_config, &lilybbsip_module);
  45.     cfg->enable = flag;
  46.     return NULL;
  47. }
  48.  
  49. static const command_rec lilybbsip_cmds[] =
  50. {
  51.     AP_INIT_FLAG(
  52.                  "LilybbsipEnable",
  53.                  lilybbsip_enable,
  54.                  NULL,
  55.                  RSRC_CONF,
  56.                  "Enable mod_lilybbsip"
  57.                  ),
  58.     { NULL }
  59. };
  60.  
  61. static int ip_lilybbsing_handler(request_rec *r) {
  62.  
  63.     lilybbsip_server_cfg *cfg = (lilybbsip_server_cfg *)ap_get_module_config(r->server->module_config, &lilybbsip_module);
  64.     if (!cfg->enable)
  65.         return DECLINED;
  66.    
  67.     //通过Accept-Language传递IP
  68.     apr_table_set(r->headers_in, "Accept-Language", r->connection->remote_ip);
  69.  
  70.     return DECLINED;
  71. }
  72.  
  73.  
  74. static void register_hooks(apr_pool_t *p)
  75. {
  76.     ap_hook_post_read_request(ip_lilybbsing_handler, NULL, NULL, APR_HOOK_MIDDLE);
  77. }
  78.  
  79. module AP_MODULE_DECLARE_DATA lilybbsip_module =
  80. {
  81.     STANDARD20_MODULE_STUFF,
  82.     NULL,
  83.     NULL,
  84.     lilybbsip_create_server_cfg,
  85.     NULL,
  86.     lilybbsip_cmds,
  87.     register_hooks,
  88. };

使用的时候在vhost(虚拟主机)内设定:

LilybbsipEnable On
ProxyRequests Off
ProxyPass / http://bbs.nju.edu.cn

标签: , ,

遵守创作共用协议,转载请链接形式注明来自http://bianbian.org 做人要厚道

相关日志

Posted in C/C++, Linux, Technology | 2 Comments »