|
|
2008/8/12 佛下山游说佛法,在一家店铺里看到一尊释迦牟尼像,青铜所铸,形体逼真,神态安然,佛大悦。若能带回寺里,开启其佛光,记世供奉,真乃一件幸事,可店铺老板要价5000元,分文不能少,加上见佛如此钟爱它,更加咬定原价不放。 佛回到寺里对众僧谈起此事,众僧很着急,问佛打算以多少钱买下它。佛说:“500元足矣。”众僧唏嘘不止:“那怎么可能?”佛说:“天理犹存,当有办法,万丈红尘,芸芸众生,欲壑难填,得不偿失啊,我佛慈悲,普度众生,当让他仅仅赚到这500元!” “怎样普度他呢?”众僧不解地问。 “让他忏悔。”佛笑答。众僧更不解了。佛说:“只管按我的吩咐去做就行了。” 第一个弟子下山去店铺里和老板侃价,弟子咬定4500元,未果回山。 第二天,第二个弟子下山去和老板侃价,咬定4000元不放,亦未果回山。 就这样,直到最后一个弟子在第九天下山时所给的价已经低到了200元。眼见着一个个买主一天天下去、一个比一个价给得低,老板很是着急,每一天他都后悔不如以前一天的价格卖给前一个人了,他深深地怨责自己太贪。到第十天时,他在心里说,今天若再有人来,无论给多少钱我也要立即出手。 第十天,佛亲自下山,说要出500元买下它,老板高兴得不得了——竟然反弹到了500元!当即出手,高兴之余另赠佛龛台一具。佛得到了那尊铜像,谢绝了龛台,单掌作揖笑曰:“欲望无边,凡事有度,一切适可而止啊!善哉,善哉……” 看帖回帖,佛祖保佑您日进斗金! gegewan点评:不要以为砍价能就占便宜,9个弟子上下山的费用谁出?9个弟子如果不下山能创造其他价值,这下也不能创造价值了(机会成本)后来佛还亲自下山,看来佛很笨,并不懂经济学。由此看来他的佛法仅是浪得虚名而已... 2008/8/11 常在小说或影视剧甚至生活中的邻里寒暄中听到这么一句: “伢都可以打酱油了。” 表面上看这是说一个小毛毛现在长大了,可是为什么要用打酱油来形容他长大了呢 话说很多年前,大多数ZG人民的生活还都不好,那时也没什么所谓的商品房,普通百姓住的都是很简陋的茅草房。一家就只有一间,夫妻、孩子都住在一起,也就是一家人只有一张床可用。孩子还小的时候就没关系啦,但是,等孩子日渐长大,肯定就会干扰大人办事,或者问一下他们在做什么,或者会跟别人讲这事什么的。 为这事,大人要嘿休就没那么随意了,晚上就基本上很难有机会,那就白天吧。那时的孩子又不像现在的,3岁就送去了幼儿园,没得书读滴,有可能成天呆在家。大人们就得想个办法把小孩支开,怎么办呢?有办法,老爸就把小孩拉过来,“儿啊,家里酱油没了,你去打点酱油回来哈……”小P孩就P巅P巅的去了。 还有一个问题,如果打酱油的地方离家太近,往返的时间很短怎么办?当然有办法,老爸就给小孩一个碗(更狠的给碟子啥的),小孩端着酱油怕洒了,就不敢走快了啦;还有一个好处是,每次少打点,才可以隔一、两天又去打酱油。 然后,就可以放心的嘿休嘿休嘿休……… 以上就为“小孩可以打酱油了”的传说中的典故了-。- 2008/8/2 由于搜索引擎工程师坚持不懈地同Spammers作斗争,所以SEO在现在更重要的是不被当作Spammer处罚而不是“优化”。你必须注意几件事,否则,你会成为搜索引擎工程师同Spammer作斗争的牺牲品。考虑到这一点,我们总结了一些技巧,这些技巧分为三类:必须,推荐,避免。 正如我们以前介绍的,SEO和你的PR值增长没有什么关系。 你应当尝试获得更多的返回链接,并且避免被搜索引擎惩罚。被惩罚的网站即使PR再高也没用。 必须:标题 你网站的每一个项目都必须有一个标题,就我们看来,这是XOOPS网站SEO最重要的部分。为网页加标题并不是那么困难,只需要有一点PHP和MySQL知识即可。如果你一点也不了解PHP和MySQL知识,那么尽快学习吧!否则你管理网站就会有麻烦了,不仅是加标题这一方面。 关于加标题的技巧,请访问如下网页: http://xoops-tips.com/news-article.storyid-69.htm 推荐:ShortURLs 顶级链接比二、三级链接要有更高的PR,ShortURLs的美妙之处在于,它把你所有的链接都转译成顶级链接。如果ShortURLs功能开启,那么你的网页要比相似内容的网页有更好的PR。 避免:被处罚 正如前面所提到的,更高的PR和搜索引擎排名没有直接关系。也许你的网站是PR6,但是如果你被处罚,那么你的网站内容可能被埋没到60或者80页。 1.访问你的网站是否有WWW 选择一种方式(有或者没有WWW),然后坚持用这种方式(做广告或者友情链接),否则你的网站会被处罚。具体技巧请访问: http://xoops-tips.com/news-article.storyid-92.htm 为什么这么重要?内容重复——如果你的网站有两份完全相同的内容(一个网址有WWW,另一个没有),那么你可能会被处罚。 2.为模块使用nofollow标签 一条技巧——如果网页上的链接只是供人类使用而不是机器,那么请用nofollow标签。 机器去“投票”、“发送给朋友”、“评论”、“打印”或者“创建PDF文件”没有什么意义。就拿news模块来说,“打印”和“创建PDF文档”将会使你的网站陷入麻烦:有三份完全相同的内容,这三份内容都会被机器录入,你的网站将会被处罚。 运用nofollow标签的技巧请访问: http://xoops-tips.com/news-article.storyid-97.htm 这个技巧是针对news模块的,但是这个技巧适用于其他的模块。 3.关键字 搜索引擎尤其讨厌关键字泛滥。新版本的news模块可以自动生成关键字,这也许会使你陷入麻烦。在Hervé发布更新版本之前,或者你想用自己的关键字,请参考这个技巧: http://xoops-tips.com/news-article.storyid-79.htm (第四部分——如何为网页添加自定义关键字) 因为关键字对搜索引擎不是那么重要,用你的标题作关键字就足够了。 4.PHPSessionIDs 请确认你的链接没有悬而未决的PHPSessionID,在Google上检查: site:www.yoursite (或者你的真实URL) 查看搜索结果, 看看是否清理掉了PHPSessionID。 清理掉PHPSessionID的技巧请访问这里: http://xoops-tips.com/news-article.storyid-62.htm 为什么PHPSessionID对网站排名有害? 因为如果你的链接有悬而未决的PHPSessionID的话,每次机器访问同一个链接却用不同的PHPSessionID,机器会认为这是一个新网址并且把它摘录。这样的话你的网站就会有巨大数量的重复内容录入搜索引擎,你的网站迟早要被惩罚。 最后关于SEO的一点思考 SEO值得你的努力吗?是的。但是头脑中要有大框架:机制性的流量增加比通过搜索引擎的流量增加更好。搜索引擎的流量增加应当是你机制性的流量增加的补充。难道xoops.org需要通过搜索引擎增加流量?不!在这种情况下,SEO没什么用处。 你应当勤奋地在SEO方面工作,缓慢但是持续地通过搜索引擎增加你的网站流量,直到你的网站发展得像xoops.org那样,运用最简单有效的SEO技巧,不要过度优化。 2008/8/1 记得小时候的某一天,忽然听到大人们在议论纷纷,说某地山上挖到万阁老的墓了。很多人跑去看,想映证一下是不是和传说中的金头人身吻合。由于当时太小,我没能去参观。旋即听说政府有关部门把墓地封存了。问大人万阁老是谁,怎么有金头。他们说万阁老是个宰相,因为被误杀了,皇帝用金子给他铸了个脑袋和身子一起埋葬。后来年纪渐长,发现全国很多地方都有当地名人金头人身下葬的传闻,甚至连 “唐宋八大家”之一的曾巩的故事都不能免俗!不知这种民间传闻从何而来,让人直想大笑。反正后来我就认为万阁老是传说中的人物,绝非真人。 上学时,家乡教育部门编了很多供我们课外阅读的乡土读物,其中有本书不知怎么又提到万阁老。书上云,据说我们这里以前有个叫万安的人,当了宰相,但却不好好做官,反而把宫中的陈娘娘给勾搭上了,竟然带着陈娘娘回到家乡。这时朝廷追兵将至,万安和陈娘娘在一座桥上洒泪相别,陈娘娘去峨眉山做了尼姑,万安不知所终。 这个故事荒诞离奇,匪夷所思。加上书上本身也标明是“据说”,即使当时的学生也不会相信这是真事。宰相要真能勾引娘娘一起私奔回乡,那简直是历史上惊天动地的大事情,当事人完全可以含笑青史永垂不朽了!可惜这样的事情,只能在戏文传说中去寻找。 而当地民间的传闻更是有趣,说万安和陈娘娘好上后缱绻缠绵,如胶如漆,后来事情走漏风声,皇帝决定收拾他们,万安还浑然不觉。陈娘娘当着别人的面不好明说,就给万安做了一碗面,却又在面碗里撒了一把茴香和几粒枣子。万安一看,顿时大悟,这分明是叫他“趁早回乡(沉枣茴香)”!于是万安捉空真带着陈娘娘跑回家乡了。这个故事当然也是破绽百出,所以依然没有相信历史上真有这么一个人物。 直到上了大学,不知在哪本书上看到古人的记述,提到“眉州万阁老”“阁老万眉州”,惊奇得目瞪口呆:原来万阁老还真存在过呀!再看《明史》,还确实有《万安传》,明确写道万安“字循吉,眉州人。”当然再看下去,就有些哭笑不得。万安做首辅时间很长,把持朝政的时间更长,百官无敢抵牾,诚为政坛强人。但他没几样突出业绩,倒是丑事不少,谄媚皇帝,勾结贵妃,历来为人诟病。和明代四川其他著名阁老相比,眉山万安权势最盛,但根本不如新都杨廷和能干,更不如内江赵贞吉正直,倒是油滑绝对数第一。 知道万安真的存在过,确实让人兴奋;但又看到万安是这样的人,未免有点失望。万安故乡眉山是四川人文之邦,历史上所出的宰相首辅一级的官员数量仅次于成都,只要看看“三苏乡”“虞丞乡”“家相乡”等地名就知道这里曾经能人辈出了。但奇怪的是,其他宰相级官员如苏辙、虞允文、家铉翁等人的贤德忠贞,均为万安所远远不及,为何在民间反倒是万安更为有名呢? 究其原因,恐怕是因为当地其他宰相大多生于元代之前,万安却出于明代。宋元之交是四川历史上一次毁灭性的劫难,加上移民的更替、文化的断层,民间往往对元代及其以前的事情有一层隔膜,对明清要亲切熟悉得多。今天当地姓苏姓虞的就极少,而姓万的却依然还很多。宋代眉山“唐宋八大家”占了三个,进士数量全川第一。降至明代,眉山进士数量不足宋时的1/10,落差太大了。在这种情况下,万安不仅高中进士,而且官至阁老,实为奇迹,自然更受瞩目。 传说当时上天是想让世间出一万名宰相,但这些家庭也要付出极大的代价,即遭遇火灾,每烧一家,该家就出一名宰相。执行任务的神仙悲天悯人,不忍心让那么多家遭受祝融之祸,于是想出一个似是而非的办法,不烧一万家,却烧一个姓万的人家;不出一万个宰相,却出一个姓万的宰相。因此这把火最后烧到了眉州尚义镇万冲村的万家,而万安也很快降生了。 万安从小就非常聪明。有一次黎明时分天上红日东升,残月未降,万家一位客人触景生情,随口说道:“日在东,月在西,天上生成明字。”年幼的万安应声而答: “子在右,女在左,世间配定好人。”让客人赞赏不已。因此万安从小读书就显示出过人的天赋。当然由于他中进士后把精力全放在如何升官上,没留下什么作品。 万安是明英宗正统年间的进士。成年后的他魁梧高大,眉目如画,竟是一个绝美的男子。这点,连正史上都忍不住进行描绘。一般来说,现在重点大学多出恐龙青蛙,美女帅哥远远少于一般大学。想来古代万里挑一的进士更是如此,上天对人是公平的,给了聪明往往就不给美貌,而太俊美的男子分心过多,也不容易高中。当年金榜题名、琼楼饮宴的时候,来自全国南北各地长相不一或老或丑的几百进士中,清俊挺拔、玉树临风的万安一定是格外的抢眼。模样漂亮容易给人好看,万安容貌俊雅、性格温和,对于他仕途上一路春风肯定是有很大帮助的,否则《明史》也不会公开强调他的帅气了。 万安后来确实步步高升,官至一人之下万人之上,成为明代著名的万阁老。可惜这些都不是他政绩优秀获得的,相反,“纸糊阁老”“万岁阁老”的名声,为皇帝搜集房中术的行为,善于归过他人自己撇清责任的做法,使他成了后世的笑柄。更让人汗颜的是,他竟然和宫中一手遮天的万贵妃认起了亲戚。万贵妃是山东诸城人,万安是四川眉山人,相距几千里,只不过都姓万,一个想借助宠妃来赢得皇帝的好感和青睐,一个想倚靠士大夫来抬高自己的身份和地位,于是眉来眼去一拍即合成了“亲戚”。 大概就是因为万安容貌英俊,又和万贵妃狼狈为奸,以讹传讹,到了后世,在万安家乡,竟被人们想象成万安和宫中的陈娘娘有了婚外恋甚至私奔的千古奇闻。 作为权相,万安留给后世的名声很不好。但他只是过于油滑,为了升官不顾身份不顾脸皮,而绝非大奸大恶之人,也算不上阴险毒辣。他从不曾像严嵩那样迫害甚至杀死很多人。利己不损人的处世思想在万安身上得到了很好的体现,所以万安最后还能得善终。而且万安也还是做过好事的,打击汪直、请罢西厂就是他促成的,为当时朝政和后世所称赞。 左右逢源、八面玲珑、千伶百俐的万安在宪宗一朝可谓炙手可热,权倾天下。到了励精图治的孝宗上台后,万安的情况就不妙了。尽管他用一贯的脱身伎俩和万贵妃划清界限,但他以前向皇帝献房中术的行为受到了孝宗的训斥。加上此时万安已经七十多岁,年事已高,于是便知趣地上书告老还乡,孝宗也顺水推舟,准许他致仕。 年迈的万安就这样退休了,黯然回到阔别多年的眉州故里。有传说称他装了很多车的金珠宝贝运回家,还有传说称他在返乡的路上还一次次回望京城,希望皇帝回心转意再次起用他。实际上,一代权相现在只是一个风烛残年的衰朽老翁了。回到家乡没两年,万安就去世了,结束了他不知该算成功还是失败的人生。 大概就是因为万安后来为皇帝所不喜,暮年颓然回到家乡,不过明朝还是有始有终,没有难为他,在他死后还“赠太师,谥文康”。以讹传讹,到了后世,竟也被人们想象成皇帝先斩首又后悔于是铸金头补偿的惯例故事。 万安不是一个以政绩出名的官员,只是一个油滑大吏,所以即使其家乡,也绝对不会把他出生的地方取个类似“万丞乡”“万相村”之类的名字来纪念,甚至连提都不愿多提他。但在民间,在家乡父老的口中,万安的传闻却如此鲜活地存在着。他从偏僻的家乡孤身赴京,考中进士,还步步高升,官至阁老,权倾天下,在没有仕宦家族背景的前提下,全靠自己一个人去努力争取别人的扶持和帮助,也真是殊为不易。虽然不择手段,但毕竟没有伤天害理,而且不管是滑头的万阁老也好,狡诈的万阁老也好,在家乡父老的眼中,他永远都是当年那个顽劣调皮的万家儿郎。 今存的万安墓位于眉山复兴乡境内,虽然是有明一代著名权相的归宿,但却只是东坡区文物保护单位而已。而且由于明清四川的战祸的影响和地理位置的偏远,万安墓久不为人所知,自明以来绝少为人所提及所凭吊所吟讽。万安是一个好热闹喜喧嚣的人,华表辽鹤,魂兮归来,盘桓于月白风清之间,松林山涧之中,面对如今无边无际的寂寞,想起身后无穷无际的非议,不知会作何感想! 万阁老的故乡在四川省眉山市东坡区尚义镇万冲村二组万辕门 万朝伟、万朝瑞兄弟收集整理 2008/7/27 tar命令 tar 文件是几个文件和(或)目录在一个文件中的集合。这是创建备份和归档的佳径。 tar 使用的选项有: -c — 创建一个新归档。 -f — 当与 -c 选项一起使用时,创建的 tar 文件使用该选项指定的文件名;当与 -x 选项 一起使用时,则解除该选项指定的归档。 -t — 显示包括在 tar 文件中的文件列表。 -v — 显示文件的归档进度。 -x — 从归档中抽取文件。 -z — 使用 gzip 来压缩 tar 文件。 -j — 使用 bzip2 来压缩 tar 文件。 要创建一个 tar 文件,键入: tar -cvf filename.tar directory/file 可以使用 tar 命令同时处理多个文件和目录,方法是将它们逐一列出,并用空格间隔: tar -cvf filename.tar /home/mine/work /home/mine/school 上面的命令把 /home/mine 目录下的 work 和 school 子目录内的所有文件都放入当前 目录中一个叫做 filename.tar 的新文件里。 要列出 tar 文件的内容,键入: tar -tvf filename.tar 要抽取 tar 文件的内容,键入 tar -xvf filename.tar 这个命令不会删除 tar 文件,但是它会把被解除归档的内容 复制到当前的工作目录下,并保留归档文件所使用的任何 目录结构。譬如,如果这个 tar 文件中包含一个叫做 bar.txt 的文件,而这个文件包含在 foo/ 目录中,那么, 抽取归档文件将会导致在你当前的工作目录中创建 foo/ 目录,该目录中包含 bar.txt 文件 tar 默认不压缩文件。 要创建一个使用 tar 和 bzip 来归档压缩的文件,使用 -j 选项: tar -cjvf filename.tbz file 以上命令创建了一个归档文件,然后将其压缩为 filename.tbz 文件。如果你使用 bunzip2 命令为 filename.tbz 文件解压,filename.tbz 文件会被删除,继之以 filename.tar 文件。 你还可以用一个命令来扩展并解除归档 bzip tar 文件: tar -xjvf filename.tbz 要创建一个用 tar 和 gzip 归档并压缩的文件,使用 -z 选项: tar -czvf filename.tgz file 这个命令创建归档文件 filename.tar,然后把它压缩为 filename.tgz 文件(文件 filename.tar 不被保留)。 如果你使用 gunzip 命令来给 filename.tgz 文件解压,filename.tgz 文件会被删除,并被 替换为 filename.tar。 你可以用单个命令来扩展 gzip tar 文件: tar -xzvf filename.tgz 一. tar 1.压缩一组文件为tar.gz后缀。 # tar cvf backup.tar /etc #gzip -q backup.tar 或 # tar cvfz backup.tar.gz /etc/ tar zxvf XXXX.tar.gz tar jxvf XXXX tar.bz2 2.释放一个后缀为tar.gz的文件。 #gunzip backup.tar.gz #tar xvf backup.tar 或 # tar xvfz backup.tar.gz 3.用一个命令完成压缩 #tar cvf - /etc/ | gzip -qc > backup.tar.gz 4.用一个命令完成释放 # gunzip -c backup.tar.gz | tar xvf - 5.如何解开tar.Z的文件? # tar xvfz backup.tar.Z 或 # uncompress backup.tar.Z #tar xvf backup.tar 6.如何解开.tgz文件? #gunzip backup.tgz 7.如何压缩和解压缩.bz2的包? #bzip2 /etc/smb.conf 这将压缩文件smb.conf成smb.conf.bz2 #bunzip2 /etc/smb.conf.bz2 这将在当前目录下还原smb.conf.bz2为smb.conf 注: .bz2压缩格式不是很常用,你可以man bzip2 2008/7/20 编者按:软件开发非常复杂,不仅包含需求分析、设计、编码、测试、实施、维护等不同的子过程,还涉及到开发工具、开发人员、项目管理、风险等众多因素,不同因素对估算产生的影响不尽相同。这里我们对几个常见的因素做一些探讨。 项目是指以一定的成本在一定时间内取得预期收益的系列活动。项目的“生命期”是管理项目的重要指标,而对项目周期的估算则是管理项目的重要一环。本期“项目管理”介绍对软件项目周期进行估算的技巧。 估算是软件开发中很重要的一个环节:项目周期估算过短会造成人力低估、成本预算低估、日程安排过短,最终人力资源耗尽,成本超出预算,为完成项目不得不赶工,影响项目质量,甚至导致项目失败;项目周期估计过长表面看来影响不大,但是实际上也会带来成本估计过高、充分效率低下的后果。周期估算如同盖楼房中打地基,是后续工作的基础,它的影响会贯穿整个项目。 但软件开发是一项非常复杂的工程,不仅包含需求分析、设计、编码、测试、实施、维护等不同的子过程,还涉及到开发工具、开发人员、项目管理、风险等众多因素,不同因素对估算产生的影响不尽相同。在进行软件估算时(包括利用工具辅助估算)必须考虑到这些方面,否则估算结果就会和实际结果有很大的偏差。下面,我们对几个常见的因素做一些探讨。 软件规模是项目估算的基础 软件规模通常指的是软件的大小,可以通过程序代码行的长度、功能函数的数量、数据库中表的数量、数据库的大小等要素来描述软件规模。一般而言,软件规模越大,所花费的开发周期就越长。但这并不是一个简单的线性函数关系,也要考虑代码重用问题。比如一个模块代码很长,但是可能包含了很多公用函数,那么在估算时就应适当减少代码行数量。 软件项目中包含的功能模块越多、越复杂(或者说软件越大),开发周期越长。这个时间绝不是模块开发时间的简单叠加,因为模块功能数量的增加直接带来了软件模块间相互关联度、复杂度的成倍增加,这导致了在需求、设计等阶段需要花费更多的时间,比单独考虑一个模块复杂得多。另一方面,对于产品化程度高的项目开发,随着模块数量增加,开发周期的增加却不是特别明显。这是因为相当数量的模块可以完全重用,实际开发量大大减少。 所以,在实际进行软件开发周期估算的时候,软件规模肯定是首先考虑的因素。具体估算时,在考虑软件规模时要去除可重用的部分。另外,软件功能之间的关联所造成的复杂性也必须足够重视。 风险影响周期 任何一个项目都或多或少存在风险,软件项目开发过程中也避免不了这种情况而且有自己的特点。最常见的风险来自于:技术、客户、项目人员等方面。开发周期估算时项目风险应该适当考虑,尤其是技术风险和客户风险—— 技术风险 技术风险主要来自于软件本身的技术难度。对于一套成熟的产品,定制开发的技术风险相对非常小,因为重要的技术已经成型,客户也很少有新的、能带来高难度技术问题的需求,这种风险较小。但是对于完全重新开发的项目,或是研发类的项目,技术风险必须特别重视。以开发平台为例,开发平台必须适合本项目所涉及的软件开发、满足最终的需求,平台的错误选择将导致庞大的开发工作量,即便满足了用户需求也可能造成系统效率低下、扩展性差的致命问题,软件可能会很快被淘汰。 在实际估算中,建议将技术难度分为十级,每一级在初次估算的代码行上增加10%, 最终估算代码长度=初始估算代码长度×(1+0.1×n) 假设模块A的初次估计代码行为15000行,但考虑技术难度高的风险,设定技术难度级别为二级,最终代码行的估算数量为15000×(1+20%)=18000。 由于技术风险的分析是一项技术性很强的工作,要求做技术风险分析的人必须是技术专家,在相关技术领域有着丰富的经验。对重大技术风险的分析结果必须要经过评审,保证准确性。 客户风险 客户风险存在于客户化项目中,客户行业特点不尽相同,技术、理解水平也相差甚远。在我经历开发的项目中,80%的项目延期是由于客户方的原因,而且这种风险可控性很低,对项目影响超过技术风险。 在开发周期估算前,项目经理要仔细分析客户的具体状况,包括客户方的计算机水平、管理水平、可沟通程度,在此基础上结合以往的经验综合判断是否会对开发带来明显的影响,可以按照上述的技术风险的方式将客户分级,最终确定开发周期。在这个过程中,项目经理的经验极其重要,对客户的分析基本上要依赖经验做判断,要求管理人员有大量的客户经验和行业分析能力。 项目团队影响速度 对于软件开发项目来说,人力资源是核心力量。人力资源对估算的影响表现在技术水平、理解能力、沟通能力等几个方面。项目技术人员编程水平、工作效率、团队适应性、沟通能力等素质,都会对开发进度产生影响,其中技术水平是最关键的因素。评价程序员的技术水平可以从编程熟练程度、编程速度、解决技术问题的能力等几个因素考虑:编程熟练程度指的是程序员使用编程工具实现软件的功能的熟悉程度;编程速度指的是完成某个功能的速度;解决技术问题的能力可以反映程序员的技术功底—如果以100%作为总和,这三个因素分别占的合适比例为70%、15%和15%。 软件开发周期估算前,应对开发人员定级,建议按新手、初级程序员、中级程序员、高级程序员来划分,每一级人员再评定上述三个因素。初次估算时可以假定开发人员为中级程序员,然后依据项目组实际人员的水平做修正,这样结果的准确度能大大提高。 宝贵的经验 依据历史数据估算软件开发周期是一种比较常见的方法,这种方法以历史软件开发周期为依据,在估算时把当前软件项目的情况与历史数据加以对比,从而得出最终结果。 按照历史数据估算开发周期的准确度还是相当高的,但这种方法只适用于对某类软件的开发,比如某个行业业务系统的开发。当要估算的软件与历史软件相差太多,比如开发工具完全不同、或者项目类型完全不同,就不能再依赖这种方法,最起码应该辅助使用其它估算法。如果没有历史数据或是开发一种新领域软件,可以使用代码行或功能点估算法,在此基础上再通过其它方法校正。 在实际使用历史数据估算法时,建议项目经理建立一个历史项目数据库。在库中包含以前所有项目的开发周期、项目规模、开发人员状况、客户状况等详细数据。当估算时根据当前项目的状况在库中寻找最类似的历史项目,然后再比较两个项目之间在项目规模、项目风险、人力资源之间的区别,我们假定历史项目开发周期为A,当前项目的周期可以依据下列公式得出: 估算项目周期 = A×(2×S+R+P+2×C)/6 S:代表软件规模 R:代表风险 P:代表人力资源 C:代表客户 (以上值均指当前项目与历史项目的比率) 实际的比较因素应该不止这些,但软件规模、风险、人力资源及客户状况是其中最重要的,对软件开发的影响也最大,所以这个公式中只考虑了这些因素。其中软件规模和客户两项占的权重最大,这也是根据项目管理经验得出的,在实际使用历史数据估算法时还可以灵活加入其它因素 2008/7/2 参考Indy例子Indy9Demos\Chat procedure TfrmMain.BroadcastMessage( WhoFrom, TheMessage : String ); var Count: Integer; List : TList; EMote, Msg : String; begin Msg := Trim(TheMessage); EMote := Trim(memEMotes.Lines.Values[Msg]); if WhoFrom <> 'System' then Msg := WhoFrom + ': ' + Msg; if EMote <> '' then Msg := Format(Trim(EMote), [WhoFrom]); List := tcpServer.Threads.LockList;<-遍历所有以连接的客户端 try for Count := 0 to List.Count -1 do try //发消息 TIdPeerThread(List.Items[Count]).Connection.WriteLn(Msg); except TIdPeerThread(List.Items[Count]).Stop; end; finally tcpServer.Threads.UnlockList; end; end; 2008/7/1 摘要:利用Delphi开发工业控制系统软件成为越来越多的开发人员的选择,而串口通信是这个过程中必须解决的问题之一。本文在对几种常用串口通信方法分析比较的基础上,着重讨论了Delphi开发环境下利用Spcomm控件实现PC机与单片机之间串口通信的方法,研究了Spcomm串口通信的关键技术问题,并通过一个实例给出了Spcomm控件在Delphi7.0串口通信中的应用。 关键词:串口通信;Delphi7.0;Spcomm控件 2008/6/30 中国人学英语都不得不背单词,我这一背就背了12年了,找到点投机取巧的经验,推荐给大家。 Rule No.1 不要背书!
大部分人背书都是背了后面忘了前面,正襟危坐几个小时,其实记住的单词没几个,为什么?因为人的瞬时记忆力只能记忆5-7个东西,比如你妈妈叫你去买菜,七样以内你能记住,要是十几样你就得用笔记了。因此背书没用,那怎么办?就是分组背,记一组,测试一组,再记下一组 Rule No.2 不要用整段时间来背单词
我看过很多人的每日计划,什么几点到几点是背单词时间。这个没用,你花几个小时光背单词,记忆效率绝对很低,脑袋都木掉,合上书一个字也想不起来。我高中的时候几届英语牛人就一个背单词方法—小卡片。每天没事就拿出来看一下,坚持不懈,效果绝对好。 Rule No.3 在遗忘临界点复习
有个伟大的艾宾浩斯记忆曲线,非常厉害,只要按照那个曲线在遗忘临界点复习,5次复习就可以终身不忘。我高中用的文曲星就支持这个功能,我坚持用了高三一年,到现在所有单词都记得特别清楚,大学四六级压根没复习,就凭那会的底子一次闯关。 Rule No.4 语境记忆
背单词绝对不能没有例句,中文的一个词你可以对他有很多种解释,英文也一样,如果没有例句帮你体会单词用法,光背词意在真正阅读的时候一定会抓瞎。我认识个老外,中国英语教育界的权威,他对我说:中国学生对单词 just recognize, never know. 所以一定要有例句。 Rule No.5 巧用学习工具
现在科技发达,学习软件很多,巧加利用才能事半功倍。评点一下我这么多年来用的学习工具吧。 首先,高中用的是文曲星上的单词记忆功能,好处是能随身携带,缺点是没有例句,而且测试的时候采取的是拼写的方式,实在太麻烦,影响速度。而且中翻英的背单词方法很不实用,必经考试的时候英翻中才是基本功。 然后,是电脑软件我爱背单词之类,优点是有例句,缺点是自动提醒功能几乎没用,因为很难做到每天都打开电脑背单词。而且测试采取的四选一英翻中,老实说,电脑自动生成的选项一点干扰性都没有,测了和没测一样。更糟糕的是一开电脑就要上网玩游戏…… 至于什么好记星之类的东西真没法说,就是炒作…… 我现在用的是一款手机背单词软件,这款产品还是比较完美。 第一,用手机背单词,可以做到随时随地利用零散时间背单词,就和用卡片背一个效果,还不用制作卡片那么麻烦。这款软件对手机要求也不高,我的诺基亚3100也能用,看他网上的宣传是所有支持java的手机都能用。 第二,它是唯一一款有例句和习题的手机背单词软件,可以语境记忆,功能几乎和电脑软件一样了。我最喜欢的是它的测试方式,它是给出例句,让你判断单词在例句中的意思,并且提供10个选项,基本没有提示性,能测出真水平。而且它把一词多义的单词算作多个单词分开记忆,可以让我们重视单词的生僻意思,因为这些生僻意思是考试中的难点。 第三,就是它的自动提醒复习功能了,这我就不用多说了,人人都是手机不离身的,等车等人的时候背背单词,定时复习,效果非常好,也十分方便。 2008/6/26 这次油价上涨的原因: 汶川加油 四川加油 北京加油 奥运加油 中国加油 导致用油需求量大幅增加,供不应求!只能涨价了 2008/3/23 这是Perl的代码 #!/usr/bin/perl
# this is a demo
print "this is a demo\n";
my $q = new CGI;
print $q->header(); 这是PHP的代码 <?php
/**
* Internal method to iteratively remove all unwanted tags and attributes
*
* @access protected
* @param string $source Input string to be 'cleaned'
* @return string $source 'cleaned' version of input parameter
*/
function remove($source)
{
$loopCounter = 0;
/*
* Iteration provides nested tag protection
*/
while ($source != $this->filterTags($source))
{
$source = $this->filterTags($source);
$loopCounter ++;
}
return $source;
}
// ?D?¡ìºÜÀÃ3??? 中文支持很烂,如果觉得还能凑合着用那么访问 Highlight4Writer官方下载 上帝造了一群鱼。这些鱼种类多样,大小各异。为了让它们具有生存本领,上帝把它们身体做成流线型,而且十分光滑,这样游动起来可以大大减少水的阻力。上帝使每种鱼拥有短而有力的鳍,使鱼能在大海中自由自在地游动。 待上帝把这些鱼们放到大海中的时候,忽然想起一个问题,鱼的身体比重大于水,这样,鱼一旦停下来,它就会向海底沉下去,沉到一定深度,就会被水的压力压死。于是,上帝赶紧找到这些鱼,又给它们一个法宝,那就是鱼鳔。鱼鳔可以自己控制气囊,鱼可以用增大缩小气囊的办法来调节沉浮。鱼有了气囊,不但可以随意沉浮,还可以停在某地休息,鱼鳔对于鱼来讲,实在是太有用了。 出乎上帝意料的是,它没有找到鲨鱼,鲨鱼是个调皮的家伙,它一入海,便消失得无影无踪。上帝想,这也许是天意吧。既然找不到鲨鱼,那么只好由它去了。上帝想,这对于鲨鱼来讲实在是太不公平了,它会由于缺少鳔很快就沦为海洋中的弱者,最后被淘汰。为此,上帝感到很悲伤。 亿万年之后,上帝忽然想看看当年它放到海中的鱼们现在到底生活得如何?它尤其想知道,当初没有鱼鳔的鲨鱼是否己经被别的鱼吃光了。 当他将海里的鱼家族都找来的时候,已经分不清鱼的品种了。因为经过亿万年的变化,所有的鱼都变了模样。上帝问:谁是当初的鲨鱼?这时,一群威猛强壮、神气飞扬的鱼游上前来,它们就是海中的霸王———鲨鱼。上帝十分惊讶,心想,这怎么可能呢?鲨鱼说,我们没有鱼鳔,就无时无刻不面对压力,因为没有鱼鳔,我们就一刻也不能停止游动,否则就会沉入海底,死无葬身之地。所以,亿万年来,我们从未停止过游动,没有停止过抗争,自然练就了最强壮的躯体。正是因为没有鱼鳔,我们才成了海中的霸王。 生活中做普通人也较容易,循常规的生活方式过活便可,尤其一纸大学文凭在手,如同水中有鱼鳔的鱼一样,在当今社会不会面临多大的生存困难。拥有鱼鳔的大小鱼儿,可在水中沉浮自如,悠闲随意。鲨鱼若一开始就拥有此物,它也只是大量平庸鱼类中的一种,是让人们连名字也记不住的那种平常鱼。但它生于忧患,根本无法沉缅安逸,它的天大本事都是被逼而出,造就了令同类闻风丧胆的可怕优势,而这一切源于它天生缺少的一件重要器官有关。 2008/3/18 提到Lazarus就不能不说FreePascal. 1.FreePascal 是纯粹的32位编译器。这一点不要被FreePascal的设计初衷所蒙蔽:最初FreePascal的设计者只是想提供一个在 linux下面的TurboPascal 7.0。然而就算在设计的最初阶段,FreePascal就已经是一个纯粹的32位编译器,这是TurboPascal 7.0所无法比拟的。 2.FreePascal 是源码跨平台的。我的意思是,当你开发好程序后,源代码能够在各种平台上编译,如果没有使用平台相关的特性,则可以实现 “一次编写,到处编译”。但是实际上,当你在linux下开发时,经常不可避免地使用linux特有的函数,而在windows上开发时经常会用到 linux所不支持的东西,在这种情况下,只好采用预编译指令来控制了。 3.FreePascal的编译速度极快,其编译出的二进制码效率非常高。具体的性能我无法给出比较客观的测试结果,但你试着编译、运行一下,就明白我说的是什么意思了。 4. 广泛支持的多种功能。在freepascal内有多种工具库的接口可供使用。比如:ncurses,opengl,xforms,x11, md5,regexpr(正则表达式),libpng,ggi,gtk,gtk2,svgalib,zlib等等,还有很多数据库的接口如oracle, postgres, mysql等等。在开发时,既可做底层开发,也可以做前端开发。可上可下,非常灵活。看看帮助文档中的unit就可以知道“底层”的这个“底”字究竟是什么意思了。
4.FreePascal是面向对象的。FreePascal的设计者最大限度地兼容了Delphi的Object Pascal语法,从而使你能够借力于面向对象技术的强大力量。FreePascal实现了大多数Delphi底层类库,使得开发非常方便。对于可视化类库,则由项目Lazarus实现。
5.FreePascal能够很好地支持图形开发,虽然不是可视化的编程,也没有比较强大的可视化类库(Lazarus正在此领域努力),但是借助于其面向对象的能力,以及对多种图形库的支持,使得用FreePascal开发图形程序成为一件非常容易的事情。大家可以下载sourceforge上的gtk2forpascal,看看上面的例子就明白了。现在FreePascal非常好地支持gtk、gtk2,也能支持较为底层的xforms、 x11编程,如果有人愿意做的话,qt编程也不难得到支持。
6.FreePascal也支持一些比较流行的新技术,如xml。另外也提供了一个rtf parser。对于网络编程也提供了很多有用的库。 Lazarus 的设计目标是应用Free Pascal,所以所有凡是Free Pascal能运行的平台,Lazarus都可以运行。最新版本能运行于Linux,Win32和FreeBSD。整个界面的外观和操作和Delphi IDE一样,因此,如果你会使用Delphi的话,用起Lazarus IDE来就一定能得心应手了。它是一个用于Free Pascal的快速应用开发(RAD)的面向对象的Pascal集成开发环境(IDE)。最新的版本利用了SynEdit,能把Delphi的代码移植到Lazarus。下面是这个IDE的一些特色:Form Designer (表单设计器)、Object Inspector (对象观察器)、Editor Options (编辑器选项)、Compiler Options (编译选项)、Environment Options (环境选项)、Project Options (项目选项)、Code Completion (代码自动完成)、Syntax Highlighting (语法高亮)等。
官方网址: http://www.lazarus.freepascal.org/ http://sourceforge.net/project/showfiles.php?group_id=89339 2008/3/16 现在自由不疼了,一年的问题就这么解决了,原来计划花500块左右来治疗的,没想到就花20块不到就好了。上海华山医院皮肤科不是盖的,推荐和我一样,老天眷顾长了跖疣的朋友去上海华山医院,不要去那些小诊所,竹杠敲死你还不一定能治好你的脚 2008/3/8 mod_cband是一个通过Apache 2模块来解决限制用户和虚拟主机带宽问题的应用,当前版本可以调整虚拟主机和用户带宽限额,最高下载速度(like in mod_bandwidth),每秒访问请求速度和最高并发访问ip连接数(like in mod_limitipconn)。 "我告诉主机服务提供商使用mod_cband,想要限制他们用户数据传输,像“每月10 Gb流量”这样。但已有了mod_curb模块,可以限制流量,但无法工作在虚拟主机和Apache 2下,所以我写了自己的模块完全适合于Apache 2 API同时支持每用户和每虚拟主机带宽限制。"(此段翻译自官方网站) FreeBSD ports path and pkg-descr info /usr/ports/www/mod_cband mod_cband is an Apache 2 module provided to solve the problem of limiting virtualhosts bandwidth usage. When the configured virtualhost’s transfer limit is exceeded, mod_cband will redirect all further requests to a location specified in the configuration file. 好了,说道这里我想这个模块的精髓之处在于完美的支持Apache 2并实现了原有两个模块的全部功能(2in1)且支持每用户和每虚拟主机带宽限制。这在进行web平台应用与整合之时给我们提供了又一易用的方法。准备动手吧!文中实例与系统平台均基于freebsd6.1平台。 提示: 在进行实际操作之前请确保你的ports tree已经同步到当前版本。具体方法请参考http://cnsnap.cn.freebsd.org/doc ... ok/ports-using.html,关于freebsd和apache2的安装本文不予介绍,同时假定你已经安装并配置了所需环境。 安装: #cd /usr/ports/www/mod_cband #make install clean 安装结束后末尾输出: chmod 755 /usr/local/libexec/apache2/mod_cband.so [activating module `cband’ in /usr/local/etc/apache2/httpd.conf] ===> Registering installation for mod_cband-0.9.7.3 此时cband_module已经自动添加到你的httpd.conf文件中并开启了。 LoadModule cband_module libexec/apache2/mod_cband.so 至此mod_cband安装已经完成,让我们继续后面的操作。之前说mod_cband易用是相对的,主要是看你如何配置让他为你所用。一些基础配置还是很容易完成,但是要发挥它的强大和灵活配置还是要好好看看documentation,充分理解良好驾驭。不��嗦了,下面看看如何进行基本配置和使用并观测实际效果。以我这个blog为实例,看看基本情况: <VirtualHost *:80> DocumentRoot “/other/blog/wordpress” ServerName blog.citygrit.cn <Directory “/other/blog/wordpress”> allow from all Options +Indexes </Directory> # 100MB virtualhost bandwidth limit CBandLimit 100M # Maximal 1024kbps speed for this virtualhost # Maximal 10 requests per second for this virtualhost # Maximal 30 open connections for this virtualhost CBandSpeed 1024 10 30 # Maximal 10kB/s speed, 3 requests/s and 2 open connections for any remote client CBandRemoteSpeed 10kb/s 3 2 # a period of time after which the scoreboard will be cleared (4 weeks) CBandPeriod 4W #Then you can access the status page with a URL like:http://server_name/cband-status <Location /cband-status> SetHandler cband-status </Location> #Then you can access the status page with a URL like:http://server_name/cband-status-me <Location /cband-status-me> SetHandler cband-status-me </Location> </VirtualHost> 为了便于理解将上面内容里与mod_cband相关设置予以说明,(约定“#”为注释标记)。 # 100MB virtualhost bandwidth limit CBandLimit 100M 限制虚拟主机总访问带宽为100Mb。 # Maximal 1024kbps speed for this virtualhost # Maximal 10 requests per second for this virtualhost # Maximal 30 open connections for this virtualhost CBandSpeed 1024 10 30 限制此虚拟主机最高访问速度1024kbps 限制此虚拟主机每秒最高接受请求数10个 限制此虚拟主机最高并发连接30个 # Maximal 10kB/s speed, 3 requests/s and 2 open connections for any remote client CBandRemoteSpeed 10kb/s 3 2 限制来自远端访问速度10kB每秒,3个请求每秒,2个连接。 # a period of time after which the scoreboard will be cleared (4 weeks) CBandPeriod 4W 设定多久对所记录的全局访问带宽进行重设(清零)。 4W=4 weeks 4周(一个月) #Then you can access the status page with a URL like:http://server_name/cband-status <Location /cband-status> SetHandler cband-status </Location> 开启了mod_cband的实时监测功能,可以通过http://server_name/cband-status进行直观的观测。(全局监测) #Then you can access the status page with a URL like:http://server_name/cband-status-me <Location /cband-status-me> SetHandler cband-status-me </Location> 开启了mod_cband的实时监测功能,可以通过http://server_name/cband-status-me进行直观的观测。(单一监测) 通过上文简单介绍了mod_cband在freebsd平台下与apache2进行整合及基本配置,整个过程属于理论结合实际操作并得以真实应用,保证其可实施性但不承诺由于其他原因造成的配置与使用问题。如果希望详细了解mod_cband的更加强大的功能和高级配置请访问其网站。本文中部分实例参考了官方网站和Manage Apache Download Speed And Traffic Limits With mod_cband这里的文章。 通告:本文系作者原创,并未抄袭互联网及其他已发表的类似文章。文中所引用 系官方网站实例及说明。欢迎转载但请注明出处已示对作者劳动成果的尊重,谢谢。如果您发现文中的表述有误请联络我,我会及时做出修正。(但不包括由于系统平台及应用软件发生变化而产生的问题) 原文链接:http://blog.citygrit.cn/?p=13 Citygrit citygrit#gmail.com 出处 作者:杨廷勇 本文介绍使用FreeBSD+Postfix+cyrus-sasl+Courier-imap+igenus+Clamav+amavisd-new来架构一个具有多域名,有webmai防病毒 和垃圾邮件并有web管理界面的邮件系统。 scyzxp, $Revision: 0.1 $Date: 2005-1-25 ________________________________________ Table of Contents 1. 系统简介 1.1 系统结构 1.2 软件介绍 2. 系统安装 2.1 安装perl 2.2 安装MySQL 2.3 安装Apache 2.4 安装PHP 2.5 安装openssl 2.6 安装phpMyAdmin 2.7 通过phpMyadmin设置数据库 2.8 安装cyrus-sasl和cyrus-sasl2-saslauthd 2.9 安装pam_mysql 2.10 安装postfix 2.11 安装expect 2.12 安装Courier-imap 3. 设置第一个用户并测试 3.1 设置第一个用户 3.2 用户登录测试 3.3 建立其他用户 4. 防病毒与防垃圾邮件 4.1 安装Clamav 4.2 安装amavisd-new 4.3 安装配置Spamassassin 5. 安装webmail 6. 邮件服务器的管理 6.1 配置apache 6.2 管理程序源代码 6.3 配置文件config.inc.php 6.4 增加域名 6.5 增加用户 6.6 查看系统状态 Chapter 1. 系统简介 本章介绍了系统的组成。 ________________________________________ 1.1 系统结构 ________________________________________ 1.2 软件介绍 ________________________________________ Chapter 2. 系统安装 安装之前:因用户数据都保存在/var目录下,因此安装FreeBSD时/var的空间应尽量大。FreeBSD的版本为4.9,按最小化安装,软件包只安装cvsup,安装结束后用cvsup更新ports树。在文档中假设服务器的ip地址为192.168.204.38,域名为test.com,主机名为mail.test.com。 ________________________________________ 2.1 安装perl 版本为5.8.5,FreeBSD缺省安装的perl版本无法支持目前的amavisd-new。 mail# cd /usr/ports/lang/perl5.8 mail# make install clean 让新版本的perl成为系统的缺省 mail# /usr/local/bin/use.perl port ________________________________________ 2.2 安装MySQL 版本为4.0.20,因目前的pam_mysql版本不支持4.1所以安装MySQL40。 mail# cd /usr/ports/databases/mysql40-server mail# make install clean ________________________________________ 2.3 安装Apache 版本为1.3.31_4。 mail# cd /usr/ports/www/apache2 mail# make install clean 编辑/etc/rc.conf,加入 Apache2_enable="YES" ________________________________________ 2.4 安装PHP 版本为4.3.10。 mail# cd /usr/ports/lang/php4 mail# make install clean 安装需要的PHP扩展模块 mail# cd /usr/ports/lang/php4-extensions mail# make install clean 注:gettext需选中 ________________________________________ 2.5 安装openssl mail# cd /usr/ports/security/openssl mail# make install clean ________________________________________ 2.6 安装phpMyAdmin mail# cd /usr/ports/databases/phpmyadmin mail# make install clean 编辑/usr/local/etc/apache/httpd.conf,加入 Alias /phpMyAdmin/ "/usr/local/www/phpMyAdmin/" Options Indexes FollowSymlinks Allowoverride AuthConfig Order allow,deny Allow from all </DIRECTORY /> 编辑编辑/usr/local/www/phpMyAdmin/.htaccess authname "MySQL Admin" authtype basic authuserfile /etc/htpasswd require user admin 运行以下命令生成可访问phpMyadmin的用户: mail# /usr/local/bin/htpasswd -c /etc/htpasswd admin 修改/usr/local/www/phpMyAdmin/config.inc.php $cfg['PmaAbsoluteUri'] = 'http://192.168.9.33/phpMyAdmin/'; 重启服务器 在浏览器输入http://192.168. 9.33/phpMyAdmin/,修改mysql数据库里user表里的root用户的密码为admin123。 重启MySQL,再编辑/usr/local/www/phpMyAdmin/config.inc.php $cfg['Servers'][$i]['password'] = 'admin123'; ________________________________________ 2.7 通过phpMyadmin设置数据库 建立两个数据库用户 #======================postfix================================== INSERT INTO user (host,user,password) VALUES('localhost','postfix',''); update user set password=password('admin123') where User='postfix'; FLUSH PRIVILEGES; GRANT ALL ON mail.* TO postfix@localhost IDENTIFIED BY "admin123"; #======================courier================================== INSERT INTO user (host,user,password) VALUES ('localhost','courier',''); update user set password=password('admin123') where User='courier'; FLUSH PRIVILEGES; GRANT select,insert,update on mail.* TO courier; 建立数据库 #=======================MAIL.SQL================================= #Create mail database CREATE DATABASE mail; use mail; #Create the aliases table CREATE TABLE aliases ( alias varchar(255) NOT NULL default '', rcpt varchar(255) default NULL, PRIMARY KEY (alias) ) TYPE=MyISAM; #Create the transport table CREATE TABLE transport ( domain char(128) NOT NULL default '', transport char(128) NOT NULL default '', UNIQUE KEY domain (domain) ) TYPE=MyISAM; #Create the virtua_users table CREATE TABLE virtual_users ( unique_id int(32) unsigned NOT NULL auto_increment, id char(128) NOT NULL default '', password char(128) default NULL, uid int(10) unsigned default '125', gid int(10) unsigned default '125', home char(255) default NULL, maildir char(255) default NULL, date_add date default NULL, time_add time default NULL, domain char(128) default NULL, name char(255) default NULL, imapok tinyint(3) unsigned default '1', ###缺省邮箱大小20M quota char(255) default '20971520', nickname varchar(10) default NULL, realname varchar(10) default NULL, office varchar(20) default NULL, PRIMARY KEY (id), KEY unique_id (unique_id) ) TYPE=MyISAM; ________________________________________ 2.8 安装cyrus-sasl和cyrus-sasl2-saslauthd mail# cd /usr/ports/security/cyrus-sasl2-saslauthd mail# make install clean 编辑/etc/rc.conf,加入 saslauthd_enable="YES" 建立一个目录连接 mail# ln -s /usr/local/lib/sasl2 /usr/lib/sasl2 配置sasl的lib库:在/etc/defaults/rc.conf文件里的ldconfig_paths="/usr/local/lib后面加上/usr/local/lib/sasl2" 运行: mail# echo pwcheck_method:saslauthd > /usr/lib/sasl2/smtpd.conf 编辑/usr/local/etc/rc.d/saslauthd.sh command="$/sbin/$" 改成: command="$/sbin/$ -r" 重启服务器 ________________________________________ 2.9 安装pam_mysql mail# cd /usr/ports/security/pam-mysql mail# make install clean mail# cp /usr/local/lib/pam_mysql.so /usr/lib/ 配置pam.conf调用mysql支持sasl认证。编辑/etc/pam.conf(将pop3 和imap的前面加上#)添加下列代码: smtp auth sufficient pam_mysql.so user=postfix passwd=admin123 host=localhost db=mail table=virtual_users usercolumn=id passwdcolumn=password crypt=1 注:以上为一行。 smtp account required pam_mysql.so user=postfix passwd=admin123 host=localhost db=mail table=virtual_users usercolumn=id passwdcolumn=password crypt=1 注:以上为一行。 注:用tab键分隔,不是用空格。密码使用crypt加密,如果使用明文密码cyrpt=0,如果 使用password()加密crypt=2 ________________________________________ 2.10 安装postfix 停止sendmail mail# killall sendmail mail# mv /usr/bin/newaliases /usr/bin/newaliases.OFF mail# mv /usr/bin/mailq /usr/bin/mailq.OFF mail# mv /usr/sbin/sendmail /usr/sbin/sendmail.OFF mail# mv /etc/rc.sendmail /etc/sendmail.OFF 开始安装postfix mail# cd /usr/ports/mail/postfix mail# make install clean 安装中选中SASL2、MySQL,及回答以下的问题。 You need user "postfix" added to group "mail". Would you like me to add it [y]? y Would you like to activate Postfix in /etc/mail/mailer.conf [n]? n 安装完进行一些设置: mail# cd /usr/local/etc/rc.d mail# ln -s /usr/local/sbin/postfix postfix.sh mail# ln -s /usr/local/sbin/sendmail /usr/sbin/sendmail mail# echo ‘postfix: root’ >> /etc/aliases mail# /usr/local/bin/newaliases mail# chown postfix:postfix /etc/opiekeys 编辑/etc/rc.conf sendmail_enable="YES" sendmail_flags="-bd" sendmail_outbound_enable="NO" sendmail_submit_enable="NO" sendmail_msp_queue_enable="NO" 编辑//etc/periodic.conf daily_clean_hoststat_enable="NO" daily_status_mail_rejects_enable="NO" daily_status_include_submit_mailq="NO" daily_submit_queuerun="NO" 修改/usr/local/etc/postfix/main.cf,在文件最后加入以下内容 #======= BASE ============== myhostname = mail.test.com mydomain = test.com home_mailbox = Maildir/ mydestination = $myhostname, $mydomain, $transport_maps local_recipient_maps = mailbox_command= /usr/local/bin/deliverquota -w 90 ~/Maildir command_directory = /usr/local/sbin #======= MYSQL ============= transport_maps = mysql:/usr/local/etc/postfix/transport.cf virtual_gid_maps = mysql:/usr/local/etc/postfix/gids.cf virtual_mailbox_base = /var/mail virtual_mailbox_maps = mysql:/usr/local/etc/postfix/mysql_virtual.cf virtual_maps = mysql:/usr/local/etc/postfix/mysql.aliases.cf virtual_uid_maps = mysql:/usr/local/etc/postfix/uids.cf #======= Quota ============ message_size_limit = 4194304 //限制每次发邮件的大小4MB virtual_mailbox_limit_inbox = no virtual_mailbox_limit_maps = mysql:/usr/local/etc/postfix/mailboxsize-mysql.cf virtual_mailbox_limit_override = yes virtual_maildir_extended = yes virtual_create_maildirsize = yes virtual_mailbox_limit = 20971520 //总邮箱的大小20MB #====== SASL ================ smtpd_sasl_auth_enable = yes smtpd_sasl_security_options = noanonymous broken_sasl_auth_clients = yes smtpd_recipient_restrictions = permit_sasl_authenticated permit_auth_destination reject #smtpd_sasl_local_domain = $mydomain smtpd_client_restrictions = permit_sasl_authenticated 确认/usr/local/etc/postfix/master.cf的配置有如下内容 virtual unix - n n - - virtual 编辑/usr/local/etc/posftix/transport.cf user = postfix password = admin123 dbname = mail table = transport select_field = transport where_field = domain hosts = localhost 编辑/usr/local/etc/postfix/gids.cf user = postfix password= admin123 dbname = mail table = virtual_users select_field = gid where_field = id hosts = localhost 编辑/usr/local/etc/postfix/uids.cf user = postfix password= admin123 dbname = mail table = virtual_users select_field = uid where_field = id hosts = localhost 编辑/usr/local/etc/posftix/mysql_virtual.cf user = postfix password= admin123 dbname = mail table = virtual_users select_field = maildir where_field = id hosts = localhost 编辑/usr/local/etc/postfix/mysql.aliases.cf user = postfix password= admin123 dbname = mail table = aliases select_field = rcpt where_field = alias hosts = localhost 编辑/etc/postfix/mailboxsize-mysql.cf user = postfix password = admin123 dbname = mail table = virtual_users select_field = quota where_field = id hosts = localhost ________________________________________ 2.11 安装expect mail# cd /usr/ports/lang/expect mail# make install clean ________________________________________ 2.12 安装Courier-imap 由于courier-imap 从 4版本开始,把 courier-authlib 独立出来了,需要先安装 courier-authlib. 具体步骤: mail# cd courier-authlib mail# make WITH_MYSQL=yes mail# make install mail# cd /usr/ports/mail/courier-imap mail# make WITHOUT_OPENSSL= yes WITH_MYSQL= yes install clean mail# cd /usr/local/etc/rc.d mail# mv courier-imap-imapd-ssl.sh.sample courier-imap-imapd-ssl.sh mail# mv courier-imap-imapd.sh.sample courier-imap-imapd.sh mail# mv courier-imap-pop3d-ssl.sh.sample courier-imap-pop3d-ssl.sh mail# mv courier-imap-pop3d.sh.sample courier-imap-pop3d.sh mail# cd /usr/local/etc/authlih mail# cd /usr/local/etc/courier-imap mail# cp authdaemonrc.dist authdaemonrc mail# cp authmysqlrc.dist authmysqlrc mail# cd /usr/local/etc/courier-imap mail# cp imapd-ssl.dist imapd-ssl mail# cp imapd.cnf.dist imapd.cnf mail# cp imapd.dist imapd mail# cp pop3d-ssl.dist pop3d-ssl mail# cp pop3d.cnf.dist pop3d.cnf mail# cp pop3d.dist pop3d 编辑修改/usr/local/etc/courier-imap/authmysqlrc 示例:authmysqlrc ##VERSION: $Id: install.sgml,v 1.1 2004/11/01 14:47:56 wt Exp $ # # Copyright 2000-2004 Double Precision, Inc. See COPYING for # distribution information. # # Do not alter lines that begin with ##, they are used when upgrading # this configuration. # # authmysqlrc created from authmysqlrc.dist by sysconftool # # DO NOT INSTALL THIS FILE with world read permissions. This file # might contain the MySQL admin password! # # Each line in this file must follow the following format: # # field[spaces|tabs]value # # That is, the name of the field, followed by spaces or tabs, followed by # field value. Trailing spaces are prohibited. ##NAME: LOCATION:0 # # The server name, userid, and password used to log in. MYSQL_SERVER localhost MYSQL_USERNAME courier MYSQL_PASSWORD admin123 ##NAME: MYSQL_SOCKET:0 # # MYSQL_SOCKET can be used with MySQL version 3.22 or later, it specifies the # filesystem pipe used for the connection # # MYSQL_SOCKET /var/mysql/mysql.sock ##NAME: MYSQL_PORT:0 # # MYSQL_PORT can be used with MySQL version 3.22 or later to specify a port to # connect to. MYSQL_PORT 3306 ##NAME: MYSQL_OPT:0 # # Leave MYSQL_OPT as 0, unless you know what you're doing. MYSQL_OPT 0 ##NAME: MYSQL_DATABASE:0 # # The name of the MySQL database we will open: MYSQL_DATABASE mail ##NAME: MYSQL_USER_TABLE:0 # # The name of the table containing your user data. See README.authmysqlrc # for the required fields in this table. MYSQL_USER_TABLE virtual_users ##NAME: MYSQL_CRYPT_PWFIELD:0 # # Either MYSQL_CRYPT_PWFIELD or MYSQL_CLEAR_PWFIELD must be defined. Both # are OK too. crypted passwords go into MYSQL_CRYPT_PWFIELD, cleartext # passwords go into MYSQL_CLEAR_PWFIELD. Cleartext passwords allow # CRAM-MD5 authentication to be implemented. MYSQL_CRYPT_PWFIELD password ##NAME: MYSQL_CLEAR_PWFIELD:0 # # # MYSQL_CLEAR_PWFIELD clear ##NAME: MYSQL_DEFAULT_DOMAIN:0 # # If DEFAULT_DOMAIN is defined, and someone tries to log in as 'user', # we will look up 'user@DEFAULT_DOMAIN' instead. # # # DEFAULT_DOMAIN example.com ##NAME: MYSQL_UID_FIELD:0 # # Other fields in the mysql table: # # MYSQL_UID_FIELD - contains the numerical userid of the account # MYSQL_UID_FIELD uid ##NAME: MYSQL_GID_FIELD:0 # # Numerical groupid of the account MYSQL_GID_FIELD gid ##NAME: MYSQL_LOGIN_FIELD:0 # # The login id, default is id. Basically the query is: # # SELECT MYSQL_UID_FIELD, MYSQL_GID_FIELD, ... WHERE id='loginid' # MYSQL_LOGIN_FIELD id ##NAME: MYSQL_HOME_FIELD:0 # MYSQL_HOME_FIELD home ##NAME: MYSQL_NAME_FIELD:0 # # The user's name (optional) MYSQL_NAME_FIELD name ##NAME: MYSQL_MAILDIR_FIELD:0 # # This is an optional field, and can be used to specify an arbitrary # location of the maildir for the account, which normally defaults to # $HOME/Maildir (where $HOME is read from MYSQL_HOME_FIELD). # # You still need to provide a MYSQL_HOME_FIELD, even if you uncomment this # out. # MYSQL_MAILDIR_FIELD maildir ##NAME: MYSQL_DEFAULTDELIVERY:0 # # Courier mail server only: optional field specifies custom mail delivery # instructions for this account (if defined) -- essentially overrides # DEFAULTDELIVERY from $/courierd # # MYSQL_DEFAULTDELIVERY defaultdelivery ##NAME: MYSQL_QUOTA_FIELD:0 # # Define MYSQL_QUOTA_FIELD to be the name of the field that can optionally # specify a maildir quota. See README.maildirquota for more information # MYSQL_QUOTA_FIELD quota ##NAME: MYSQL_AUXOPTIONS:0 # # Auxiliary options. The MYSQL_AUXOPTIONS field should be a char field that # contains a single string consisting of comma-separated "ATTRIBUTE=NAME" # pairs. These names are additional attributes that define various per-account # "options", as given in INSTALL's description of the "Account OPTIONS" # setting. # # MYSQL_AUXOPTIONS_FIELD auxoptions # # You might want to try something like this, if you'd like to use a bunch # of individual fields, instead of a single text blob: # # MYSQL_AUXOPTIONS_FIELD CONCAT("disableimap=",disableimap,", #disablepop3=",disablepop3,",di #sablewebmail=",disablewebmail,",sharedgroup=",sharedgroup) # # This will let you define fields called "disableimap", etc, with the end result # being something that the OPTIONS parser understands. ##NAME: MYSQL_WHERE_CLAUSE:0 # # This is optional, MYSQL_WHERE_CLAUSE can be basically set to an arbitrary # fixed string that is appended to the WHERE clause of our query # # MYSQL_WHERE_CLAUSE server='mailhost.example.com' ##NAME: MYSQL_SELECT_CLAUSE:0 # # (EXPERIMENTAL) # This is optional, MYSQL_SELECT_CLAUSE can be set when you have a database, # which is structuraly different from proposed. The fixed string will # be used to do a SELECT operation on database, which should return fields # in order specified bellow: # # username, cryptpw, clearpw, uid, gid, home, maildir, quota, fullname, options # # The username field should include the domain (see example below). # # Enabling this option causes ignorance of any other field-related # options, excluding default domain. # # There are two variables, which you can use. Substitution will be made # for them, so you can put entered username (local part) and domain name # in the right place of your query. These variables are: # $(local_part), $(domain), $(service) # # If a $(domain) is empty (not given by the remote user) the default domain # name is used in its place. # # $(service) will expand out to the service being authenticated: imap, imaps, # pop3 or pop3s. Courier mail server only: service will also expand out to # "courier", when searching for local mail account's location. In this case, # if the "maildir" field is not empty it will be used in place of # DEFAULTDELIVERY. Courier mail server will also use esmtp when doing # authenticated ESMTP. # # This example is a little bit modified adaptation of vmail-sql # database scheme: # # MYSQL_SELECT_CLAUSE SELECT CONCAT(popbox.local_part, '@', popbox.domain_name), \ # CONCAT('', popbox.password_hash), \ # popbox.clearpw, \ # domain.uid, \ # domain.gid, \ # CONCAT(domain.path, '/', popbox.mbox_name), \ # '', \ # domain.quota, \ # '', \ # CONCAT("disableimap=",disableimap,",disablepop3=", \ # disablepop3,",disablewebmail=",disablewebmail, \ # ",sharedgroup=",sharedgroup) \ # FROM popbox, domain \ # WHERE popbox.local_part = '$(local_part)' \ # AND popbox.domain_name = '$(domain)' \ # AND popbox.domain_name = domain.domain_name ##NAME: MYSQL_ENUMERATE_CLAUSE:0 # # # Optional custom SQL query used to enumerate accounts for authenumerate, # in order to compile a list of accounts for shared folders. The query # should return the following fields: name, uid, gid, homedir, maildir # # Example: # MYSQL_ENUMERATE_CLAUSE SELECT CONCAT(popbox.local_part, '@', #popbox.domain_name), \ # domain.uid, \ # domain.gid, \ # CONCAT(domain.path, '/', popbox.mbox_name), \ # '' \ # FROM popbox, domain \ # WHERE popbox.local_part = '$(local_part)' \ # AND popbox.domain_name = '$(domain)' \ # AND popbox.domain_name = domain.domain_name ##NAME: MYSQL_CHPASS_CLAUSE:0 # # (EXPERIMENTAL) # This is optional, MYSQL_CHPASS_CLAUSE can be set when you have a database, # which is structuraly different from proposed. The fixed string will # be used to do an UPDATE operation on database. In other words, it is # used, when changing password. # # There are four variables, which you can use. Substitution will be made # for them, so you can put entered username (local part) and domain name # in the right place of your query. There variables are: # $(local_part) , $(domain) , $(newpass) , $(newpass_crypt) # # If a $(domain) is empty (not given by the remote user) the default domain # name is used in its place. # $(newpass) contains plain password # $(newpass_crypt) contains its crypted form # # MYSQL_CHPASS_CLAUSE UPDATE popbox \ # SET clearpw='$(newpass)', \ # password_hash='$(newpass_crypt)' \ # WHERE local_part='$(local_part)' \ # AND domain_name='$(domain)' # 重启服务器 ________________________________________ Chapter 3. 设置第一个用户并测试 本章介绍如何开通用户,并且测试系统是否正常。 ________________________________________ 3.1 设置第一个用户 设置第一个用户 mail# mysql mysql> use mail; mysql> show tables; +----------------+ | Tables_in_mail | +----------------+ | aliases | | transport | | virtual_users | +----------------+ mysql> desc aliases; +-------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+-------+ | alias | varchar(255) | | PRI | | | | rcpt | varchar(255) | YES | | NULL | | +-------+--------------+------+-----+---------+-------+ mysql> insert aliases values('postmaster@test.com','webmaster@test.com'); mysql> select * from aliases; +--------------------------+--------------------+ | alias | rcpt | +--------------------------+--------------------+ | postmaster@test.com | webmaster@test.com | +--------------------------+--------------------+ mysql> desc transport; +-----------+-----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+-----------+------+-----+---------+-------+ | domain | char(128) | | PRI | | | | transport | char(128) | | | | | +-----------+-----------+------+-----+---------+-------+ mysql> insert transport values('test.com','virtual:'); mysql> select * from transport; +---------------+-----------+ | domain | transport | +---------------+-----------+ | test.com | virtual: | +---------------+-----------+ mysql> desc virtual_users; +-----------+---------------------+------+-----+----------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+---------------------+------+-----+----------+----------------+ | unique_id | int(32) unsigned | | MUL | NULL | auto_increment | | id | char(128) | | PRI | | | | password | char(128) | YES | | NULL | | | uid | int(10) unsigned | YES | | 104 | | | gid | int(10) unsigned | YES | | 104 | | | home | char(255) | YES | | NULL | | | maildir | char(255) | YES | | NULL | | | date_add | date | YES | | NULL | | | time_add | time | YES | | NULL | | | domain | char(128) | YES | | NULL | | | name | char(255) | YES | | NULL | | | imapok | tinyint(3) unsigned | YES | | 1 | | | quota | char(255) | YES | | 10485760 | | +-----------+---------------------+------+-----+----------+----------------+ mysql> INSERT INTO virtual_users mysql> (id,home,password,maildir,date_add,time_add,domain,name) mysql> VALUES ('webmaster@test.com','/var/mail/',encrypt('admin123'), mysql> 'test.com/webmaster/Maildir/','2004-08-08','16:28:24','test.com','webmaster'); mysql> quit 设置用户的目录与权限: mail# mkdir -p /var/mail/test.com/webmaster mail# /usr/local/bin/maildirmake /var/mail/test.com/webmaster/Maildir mail# chmod -R 777 /var/mail/test.com/ mail# chown -R postfix:postfix /var/mail/test.com 至此用户设置完毕,这里只使用一个域名,同理可以设置多个域名。 ________________________________________ 3.2 用户登录测试 用户登录测试 安装p5-MIME-Base64 mail# cd /usr/ports/converters/p5-MIME-Base64/ mail# make install clean 通过p5-MIME-Base64来取得用户名和密码的base64编码 mail# perl -MMIME::Base64 -e 'print encode_base64("webmaster\@test.com");' d2VibWFzdGVyQG1za2Uub3Jn mail# perl -MMIME::Base64 -e 'print encode_base64("admin123");' bHUwOTIx 发送邮件: mail# telnet 127.0.0.1 25 Trying 127.0.0.1... Connected to 0. Escape character is '^]'. 220 mail.test.com ESMTP Postfix ehlo mail 250-mail.test.com 250-PIPELINING 250-SIZE 4194304 250-VRFY 250-ETRN 250-AUTH NTLM LOGIN PLAIN OTP 250-AUTH=NTLM LOGIN PLAIN OTP 250 8BITMIME auth login 334 VXNlcm5hbWU6 d2VibWFzdGVyQG1za2Uub3Jn //此为用户名id:webmaster@test.com 334 UGFzc3dvcmQ6 bHUwOTIx //此为用户密码password:admin123 235 Authentication successful MAIL FROM:webmaster@test.com //告诉服务器发件人的Email地址 250 Ok RCPT TO:webmaster@test.com //告诉服务器收件人的地址 250 OK DATA //告诉服务器开始写信 354 End data with . SUBJECT:test //subject后面填写的是邮件的主题 test . //换行后输入.后按回车,表示信件内容书写完毕 250 Ok: queued as 58DC71D5 quit //发送信件,结束对话,退出SMTP服务器 221 Bye Connection closed by foreign host 收取邮件: mail# telnet 127.0.0.1 110 Trying 127.0.0.1... Connected to 0 Escape character is '^]' +OK Hello there user webmaster@test.com +OK Password required pass admin123 +OK logged in list +OK POP3 clients that break here, they violate STD53 1 2217 . retr 1 //返回第一封信的全部内容 +OK 2217 octets follow. Return-Path: <webmaster@test.com> X-Original-To: webmaster@test.com Delivered-To: webmaster@test.com Received: from mail (localhost.test.com [127.0.0.1]) by mail.test.com (Postfix) with ESMTP id 58DC71D5 for <webmaster@test.com>; Mon, 9 Aug 2004 21:11:20 +0800 (CST) SUBJECT:test Message-Id: <20040809131120.58DC71D5@mail.test.com> Date: Mon, 9 Aug 2004 21:11:20 +0800 (CST) From: webmaster@test.com To: undisclosed-recipients:; test . dele 1 //删除 +OK Deleted quit +OK Bye-bye Connection closed by foreign host 也可以使用任何其它的邮件客户端程序来测试,如foxmail、Outlook Express等等。 2008/2/15 引用 Python和Perl的笑话
刚才看到的...很强 ;-) Q: 在python里边怎么获得一个随机的字符串? A: 读入一个perl文件
|