2007-07-10

[Mac OS X] Adding a User From the Command Line

Adding a User From the Command Line

This section shows a simple example of using the Directory Service command-line tool, dscl(1), to add a user to the system. The example specifies some of the properties that you would normally associate with any user.

Note: These commands must be run as the root user. If you are executing them from the command line manually, you should do this with sudo(8). If you are using them in a script, you should use sudo when running the script.

  1. Create a new entry in the local (/) domain under the category /users.

    dscl / -create /Users/portingunix

  2. Create and set the shell property to bash.

    dscl / -create /Users/portingunix UserShell /bin/bash

  3. Create and set the user’s full name.

    dscl / -create /Users/portingunix RealName "Porting Unix Applications To Mac OS X"

  4. Create and set the user’s ID.

    dscl / -create /Users/portingunix UniqueID 503

  5. Create and set the user’s group ID property.

    dscl / -create /Users/portingunix PrimaryGroupID 1000

  6. Create and set the user home directory. (Despite the name NFSHomeDirectory, this is the local path to the home directory.)

    dscl / -create /Users/portingunix NFSHomeDirectory /Local/Users/portingunix

  7. Set the password.

    dscl / -passwd /Users/portingunix PASSWORD

    or

    passwd portingunix

  8. To make that user useful, you might want to add them to the admin group.

    dscl / -append /Groups/admin GroupMembership portingunix

This is essentially what System Preferences does when it makes a new user, but the process is presented here so you can see more clearly what is going on behind the scenes with the NetInfo database. A look through the hierarchies in the NetInfo Manager application also helps you understand how the database is organized.

2007-07-09

svn+ssh configuration

Tunneling over SSH

svnserve's built-in authentication can be very handy, because it avoids the need to create real system accounts. On the other hand, some administrators already have well-established SSH authentication frameworks in place. In these situations, all of the project's users already have system accounts and the ability to “SSH into” the server machine.

It's easy to use SSH in conjunction with svnserve. The client simply uses the svn+ssh:// URL schema to connect:

$ whoami
harry

$ svn list svn+ssh://host.example.com/repos/project
harry@host.example.com's password: *****

foo
bar
baz

In this example, the Subversion client is invoking a local ssh process, connecting to host.example.com, authenticating as the user harry, then spawning a private svnserve process on the remote machine running as the user harry. The svnserve command is being invoked in tunnel mode (-t) and its network protocol is being “tunneled” over the encrypted connection by ssh, the tunnel-agent. svnserve is aware that it's running as the user harry, and if the client performs a commit, the authenticated username will be attributed as the author of the new revision.

The important thing to understand here is that the Subversion client is not connecting to a running svnserve daemon. This method of access doesn't require a daemon, nor does it notice one if present. It relies wholly on the ability of ssh to spawn a temporary svnserve process, which then terminates when the network connection is closed.

When using svn+ssh:// URLs to access a repository, remember that it's the ssh program prompting for authentication, and not the svn client program. That means there's no automatic password caching going on (see the section called “Client Credentials Caching”). The Subversion client often makes multiple connections to the repository, though users don't normally notice this due to the password caching feature. When using svn+ssh:// URLs, however, users may be annoyed by ssh repeatedly asking for a password for every outbound connection. The solution is to use a separate SSH password-caching tool like ssh-agent on a Unix-like system, or pageant on Windows.

When running over a tunnel, authorization is primarily controlled by operating system permissions to the repository's database files; it's very much the same as if Harry were accessing the repository directly via a file:// URL. If multiple system users are going to be accessing the repository directly, you may want to place them into a common group, and you'll need to be careful about umasks. (Be sure to read the section called “Supporting Multiple Repository Access Methods”.) But even in the case of tunneling, the svnserve.conf file can still be used to block access, by simply setting auth-access = read or auth-access = none. [43]

You'd think that the story of SSH tunneling would end here, but it doesn't. Subversion allows you to create custom tunnel behaviors in your run-time config file (see the section called “Runtime Configuration Area”). For example, suppose you want to use RSH instead of SSH. In the [tunnels] section of your config file, simply define it like this:

[tunnels]
rsh = rsh

And now, you can use this new tunnel definition by using a URL schema that matches the name of your new variable: svn+rsh://host/path. When using the new URL schema, the Subversion client will actually be running the command rsh host svnserve -t behind the scenes. If you include a username in the URL (for example, svn+rsh://username@host/path) the client will also include that in its command (rsh username@host svnserve -t). But you can define new tunneling schemes to be much more clever than that:

[tunnels]
joessh = $JOESSH /opt/alternate/ssh -p 29934

This example demonstrates a couple of things. First, it shows how to make the Subversion client launch a very specific tunneling binary (the one located at /opt/alternate/ssh) with specific options. In this case, accessing a svn+joessh:// URL would invoke the particular SSH binary with -p 29934 as arguments—useful if you want the tunnel program to connect to a non-standard port.

Second, it shows how to define a custom environment variable that can override the name of the tunneling program. Setting the SVN_SSH environment variable is a convenient way to override the default SSH tunnel agent. But if you need to have several different overrides for different servers, each perhaps contacting a different port or passing a different set of options to SSH, you can use the mechanism demonstrated in this example. Now if we were to set the JOESSH environment variable, its value would override the entire value of the tunnel variable—$JOESSH would be executed instead of /opt/alternate/ssh -p 29934.

SSH configuration tricks

It's not only possible to control the way in which the client invokes ssh, but also to control the behavior of sshd on your server machine. In this section, we'll show how to control the exact svnserve command executed by sshd, as well as how to have multiple users share a single system account.

Initial setup

To begin, locate the home directory of the account you'll be using to launch svnserve. Make sure the account has an SSH public/private keypair installed, and that the user can log in via public-key authentication. Password authentication will not work, since all of the following SSH tricks revolve around using the SSH authorized_keys file.

If it doesn't already exist, create the authorized_keys file (on Unix, typically ~/.ssh/authorized_keys). Each line in this file describes a public key that is allowed to connect. The lines are typically of the form:

  ssh-dsa AAAABtce9euch… user@example.com

The first field describes the type of key, the second field is the uuencoded key itself, and the third field is a comment. However, it's a lesser known fact that the entire line can be preceded by a command field:

  command="program" ssh-dsa AAAABtce9euch… user@example.com

When the command field is set, the SSH daemon will run the named program instead of the typical svnserve -t invocation that the Subversion client asks for. This opens the door to a number of server-side tricks. In the following examples, we abbreviate the lines of the file as:

  command="program" TYPE KEY COMMENT

Controlling the invoked command

Because we can specify the executed server-side command, it's easy to name a specific svnserve binary to run and to pass it extra arguments:

  command="/path/to/svnserve -t -r /virtual/root" TYPE KEY COMMENT

In this example, /path/to/svnserve might be a custom wrapper script around svnserve which sets the umask (see the section called “Supporting Multiple Repository Access Methods”). It also shows how to anchor svnserve in a virtual root directory, just as one often does when running svnserve as a daemon process. This might be done either to restrict access to parts of the system, or simply to relieve the user of having to type an absolute path in the svn+ssh:// URL.

It's also possible to have multiple users share a single account. Instead of creating a separate system account for each user, generate a public/private keypair for each person. Then place each public key into the authorized_users file, one per line, and use the --tunnel-user option:

  command="svnserve -t --tunnel-user=harry" TYPE1 KEY1 harry@example.com
command="svnserve -t --tunnel-user=sally" TYPE2 KEY2 sally@example.com

This example allows both Harry and Sally to connect to the same account via public-key authentication. Each of them has a custom command that will be executed; the --tunnel-user option tells svnserve -t to assume that the named argument is the authenticated user. Without --tunnel-user, it would appear as though all commits were coming from the one shared system account.

A final word of caution: giving a user access to the server via public-key in a shared account might still allow other forms of SSH access, even if you've set the command value in authorized_keys. For example, the user may still get shell access through SSH, or be able to perform X11 or general port-forwarding through your server. To give the user as little permission as possible, you may want to specify a number of restrictive options immediately after the command:

  command="svnserve -t --tunnel-user=harry",no-port-forwarding,\
no-agent-forwarding,no-X11-forwarding,no-pty \
TYPE1 KEY1 harry@example.com

svn+ssh does not support non-standard port

目前 svn+ssh://user@server/path 不能指定 ssh 的 port, 已经有人发了 bug.

[转] PuTTY 中文教程

http://blog.chinaunix.net/u/553/showart.php?id=335551
http://docs.google.com/View?docid=ajbgz6fp3pjh_2dwwwwt

2007-07-07

Inblogs.net blocked?

近日用 www.inblogs.net 也不能访问 blogspot 了,难道也被 GFW 给 block 了?

ssh 相关的几个环境变量

SSH_CLIENT='192.168.3.102 1051 10022'
SSH_CONNECTION='192.168.3.102 1051 192.168.3.38 10022'
SSH_TTY=/dev/pts/0

其中 SSH_TTY 只有在 interactive shell 中才会被设置.

Google Code: Failed to checkout svn repository

svn { ls | cat | info } http://xxx.googlecode.com/svn 等命令都 work,就是不能 checkout:

$ svn co http://xxx.googlecode.com/svn
svn: REPORT request failed on '/svn/!svn/vcc/default'
svn: REPORT of '/svn/!svn/vcc/default': 400 Bad Request (http://huan.googlecode.com)
$

但是用 https 的话就能 checkout,不知何故,有人说是跟 firewall 上的设置有关。

(回家用俺的 ADSL 试了一下,没有问题,看来是公司的 firewall 把 http 的 svn checkout 给 block 了)

Upload your svn repository to Google Code

今日听 jiahuan 说可以在 Google Code 上创建自己的 svn repository,好是激动了一番,俺早就想找个地方安置俺的 svn 目录了。

申请步骤很简单,到 http://code.google.com/hosting/ 创建一个 new project 就成了。每个 project 空间好像是 100M,一般来说足够用了。project 创建之后就可以用 svn client 往里面添加内容了;另外 google code 也允许把一个已经存在的 svn repository 用 svnsync 给 upload 上去,着实方便。唯一一点不足之处是,project 里面的的所有东西都是 open 的,任何人都能够 svn checkout,不爽,一点隐私都没有!看来目前俺还不能充分利用 Google Code 的这个 service。:-(

svnsync

From: http://svn.collab.net/repos/svn/trunk/notes/svnsync.txt

==== What Is It? ====

svnsync is a tool for creating and maintaining read-only mirrors of
subversion repositories. It works by replaying commits that occurred
in one repository and committing it into another.

==== Basic Setup ====

First, you need to create your destination repository:

$ svnadmin create dest

Because svnsync uses revprops to keep track of bookkeeping information
(and because it copies revprops from the source to the destination)
it needs to be able to change revprops on your destination repository.
To do this you'll need to set up a pre-revprop-change hook script that
lets the user you'll run svnsync as make arbitrary propchanges.

$ cat <<'EOF' > dest/hooks/pre-revprop-change
#!/bin/sh
USER="$3"

if [ "$USER" = "svnsync" ]; then exit 0; fi

echo "Only the svnsync user can change revprops" >&2
exit 1
EOF
$ chmod +x dest/hooks/pre-revprop-change

$ svnsync init --username svnsync file://`pwd`/dest \
http://svn.example.org/source/repos
Copied properties for revision 0
$

Note that the arguments to 'svnsync init' are two arbitrary repository
URLs. The first is the destination, which must be empty, and the second
is the source.

Now you can just run the 'svnsync sync' command to synchronize pending
revisions. This will copy any revisions that exist in the source repos
but don't exist in the destination repos.

$ svnsync sync file://`pwd`/dest
Committed revision 1.
Copied properties for revision 1.
Committed revision 2.
Copied properties for revision 2.
Committed revision 3.
Copied properties for revision 3.
...

==== Locks ====

If you kill a sync while it's occurring there's a chance that it might
leave the repository "locked". svnsync ensures that only one svnsync
process is copying data into a given destination repository at a time
by creating a svn:sync-lock revprop on revision zero of the destination
repository. If that property is there, but you're sure no svnsync is
actually running, you can unlock the repository by deleting that revprop.

$ svn pdel --revprop -r 0 svn:sync-lock file://`pwd`/dest

==== FAQ ====

Q: So what can I do with this thing anyway?

A: Well, anything that's read-only. As long as you don't commit changes
to the destination repository you're all set. This means destination
repositories are good for providing offsite mirrors, read-only mirrors,
etc.

Q: What if I want to check out from a mirror, but commit to the master?

A: That's possible, but requires some gymnastics. You see, each repository
has its own UUID, which is stored in the working copy, so if you check
out from the mirror, and then do a 'svn switch --relocate' to point to
the master it'll error out. To make this work you need to make sure that
the mirrors have the same UUID as the master. You can set a repository
UUID via the following technique:

$ cat - <

vim 中编辑不同编码的文件时需要注意的一些地方 - ChinaUnix


此文讲解的是vim编辑多字节编码文档(中文)所要了解的一些基础知识,注意其没有涉及gvim,纯指字符终端下的vim。
vim编码方面的基础知识:

  • 存在3个变量:
encoding—-该选项使用于缓冲的文本(你正在编辑的文件),寄存器,Vim 脚本文件等等。你可以把 ‘encoding’ 选项当作是对 Vim 内部运行机制的设定。
fileencoding—-该选项是vim写入文件时采用的编码类型。
termencoding—-该选项代表输出到客户终端(Term)采用的编码类型。

  • 此3个变量的默认值:
encoding—-与系统当前locale相同,所以编辑文件的时候要考虑当前locale,否则要设置的东西就比较多了。
fileencoding—-vim打开文件时自动辨认其编码,fileencoding就为辨认的值。为空则保存文件时采用encoding的编码,如果没有修改encoding,那值就是系统当前locale了。
termencoding—-默认空值,也就是输出到终端不进行编码转换。

由此可见,编辑不同编码文件需要注意的地方不仅仅是这3个变量,还有系统当前locale和文件本身编码以及自动编码识别、客户运行vim的终端所使用的编码类型3个关键点,这3个关键点影响着3个变量的设定。
如果有人问:为什么我用vim打开中文文档的时候出现乱码?
答案是不确定的,原因上面已经讲了,不搞清楚这3个关键点和这3个变量的设定值,出现乱码是正常的,倒是不出现乱码那反倒是凑巧的。

再来看一下常见情况下这三个关键点的值以及在这种情况下这3个变量的值:

  • locale—-目前大部分Linux系统已经将utf-8作为默认locale了,不过也有可能不是,例如有些系统使用中文locale zh_CN.GB18030。在locale为utf-8的情况下,启动vim后encoding将会设置为utf-8,这是兼容性最好的方式,因为内部 处理使用utf-8的话,无论外部存储编码为何都可以进行无缺损转换。locale决定了vim内部处理数据的编码,也就是encoding。
  • 文件的编码以及自动编码识别—-这方面牵扯到各种编码的规则,就不一一细讲了。但需要明白的是,文件编码类型并不是保存在文件内的,也就是说没有任何 描述性的字段来记录文档是何种编码类型的。因此我们在编辑文档的时候,要么必须知道这文档保存时是以什么编码保存的,要么通过另外的一些手段来断定编码类 型,这另外的手段,就是通过某些编码的码表特征来断定,例如每个字符占用的字节数,每个字符的ascii值是否都大于某个字段来断定这个文件属于何种编 码。这种方式vim也使用了,这就是vim的自动编码识别机制了。但这种机制由于编码各式各样,不可能每种编码都有显著的特征来辨别,所以是不可能 100%准确的。对于我们GB2312编码,由于其中文是使用了2个acsii值高于127的字符组成汉字字符的,因此不可能把gb2312编码的文件与 latin1编码区分开来,因此自动识别编码的机制对于gb2312是不成功的,它只会将文件辨识为latin1编码。此问题同样出现在gbk,big5 上等。因此我们在编辑此类文档时,需要手工设定encoding和fileencoding。如果文档编码为utf-8时,一般vim都能自动识别正确的 编码。
  • 客户运行vim的终端所使用的编码类型—-同第二条一样,这也是一个比较难以断定的关键点。第二个关键点决定着从文件读取内容和写入内容到文件时使用 的编码,而此关键点则决定vim输出内容到终端时使用的编码,如果此编码类型和终端认为它收到的数据的编码类型不同,则又会产生乱码问题。在linux本 地X环境下,一般终端都认为其接收的数据的编码类型和系统locale类型相符,因此不需关心此方面是否存在问题。但如果牵涉到远程终端,例如ssh登录 服务器,则问题就有可能出现了。例如从1台locale为GB2310的系统(称作客户机)ssh到locale为utf-8的系统(称作服务器)并开启 vim编辑文档,在不加任何改动的情况下,服务器返回的数据为utf-8的,但客户机认为服务器返回的数据是gb2312的,按照gb2312来解释数 据,则肯定就是乱码了,这时就需要设置termencoding为gb2312来解决这个问题。此问题更多出现在我们的windows desktop机远程ssh登录服务器的情况下,这里牵扯到不同系统的编码转换问题。所以又与windows本身以及ssh客户端有很大相关性。在 windows下存在两种编码类型的软件,一种是本身就为unicode编码方式编写的软件,一种是ansi软件,也就是程序处理数据直接采用字节流,不 关心编码。前一种程序可以在任何语言的windows上正确显示多国语言,而后一种则编写在何种语言的系统上则只能在何种语言的系统上显示正确的文字。对 于这两种类型的程序,我们需要区别对待。以ssh客户端为例,我们使用的putty是unicode软件,而secure CRT则是ansi 软件。对于前者,我们要正确处理中文,只要保证vim输出到终端的编码为utf-8即可,就是termencoding=utf-8。但对于后者,一方面 我们要确认我们的windows系统默认代码页为cp936(中文windows默认值),另一方面要确认vim设置的termencoding= cp936。

最后来看看处理中文文档最典型的几种情况和设置方式:

  • 系统locale是utf-8(很多linux系统默认的locale形式),编辑的文档是GB2312或GBK形式的(Windows记事本默认保 存形式,大部分编辑器也默认保存为这个形式,所以最常见),终端类型utf-8(也就是假定客户端是putty类的unicode软件)则vim打开文档后,encoding=utf-8(locale决定的),fileencoding=latin1(自动编码判断机制不准导致的),termencoding=空(默认无需转换term编码),显示文件为乱码。

    • 解决方案 1

首先要修正fileencoding为cp936或者euc-cn(二者一样的,只不过叫法不同),注意修正的方法不是:set fileencoding=cp936,这只是将文件保存为cp936,正确的方法是重新以cp936的编码方式加载文件为:edit ++enc=cp936,可以简写为:e ++enc=cp936。

    • 解决方案2

临时改变vim运行的locale环境,方法是以LANG=zh_CN vim abc.txt的方式来启动vim,则此时encoding=euc-cn(locale决定的),fileencoding=空(此locale下文件 编码自动判别功能不启用,所以fileencoding为文件本身编码方式不变,也就是euc-cn),termencoding=空(默认值,为空则等 于encoding)此时还是乱码的,因为我们的ssh终端认为接受的数据为utf-8,但vim发送数据为euc-cn,所以还是不对。此时再用命令: set termencoding=utf-8将终端数据输出为utf-8,则显示正常。

  • 情况与前面基本相同,只是使用的ssh软件为secure CRT类ansi类软件。

vim打开文档后,encoding=utf-8(locale决定的),fileencoding=latin1(自动编码判断机制不准导致的),termencoding=空(默认无需转换term编码),显示文件为乱码。

    • 解决方案 1

首先要保证运行secure CRT的windows机器的默认代码页为CP936,这一点中文windows已经是默认设置了。其他的与上面方案1相同,只是要增加一步,:set termencoding=cp936

    • 解决方案 2

与上面方案2类似,不过最后一步修改termencoding省略即可,在此情况下需要的修改最少,只要以locale为zh_CN开启 vim,则encoding=euc-cn,fileencoding和termencoding都为空即为encoding的值,是最理想的一种情况。

可见理解这3个关键点和3个参数的意义,对于编码问题有很大助力,以后就可以随心所欲的处理文档了,同时不仅仅是应用于vim,在其他需要编码转换的环境里,都可以应用类似的思路来处理问题解决问题。

最后推荐一款功能强大的windows下的ssh客户端—-xshell,它具有类似secure CRT一样的多tab 的ssh窗口的能力,但最为方便的是这款工具还有改变Term编码的功能,这样我们就可以不用频繁调整termencoding,只需在ssh软件里切换 编码即可,这是我用过的最为方便的ssh工具。它是商业软件,但非注册用户使用没有任何限制,只是30天试用期超出后会每次启动都提示注册,对于功能没有 丝毫影响。

Controlling your locale with environment variables

Controlling your locale with environment variables

By Bill Poser on May 01, 2006 (8:00:00 AM)

People all over the world use Linux in dozens of languages. Since Linux's source code is free and open, speakers of minority languages can add support for their languages themselves, even though a large corporation might not consider them a worthwhile market. If you use more than one language, or a language other than English, you should know about Linux's use of locales to support different languages. Indeed, understanding locales can be useful even if you only use English.

You choose your locale by setting environment variables. Different variables control different things. LC_MESSAGES determines the language and encoding of messages as well as of labels in GUI components if they use GNU gettext or one of its relatives to obtain translations. A few programs obtain translations in other ways and may not be affected by LC_MESSAGES.

LC_CTYPE defines character classes, which are named sets of characters used by a variety of programs, especially regular expression matchers. In programs such as grep that use character classes like [:alnum:], class membership varies with locale. If the writing system distinguishes upper- and lower-case letters, LC_CTYPE specifies the relationship between the two.

Sort order is controlled by LC_COLLATE. Sort orders can differ within the same writing system. In ASCII order, the upper-case letters as a group precede the lower-case letters: A B C ... a b c.... In French, upper-case letters immediately follow their lower-case counterparts: a A b B c C.... In some other locales upper-case letters immediately precede their lower-case counterparts: A a B b C c....

Sort order affects not only sorting but character ranges in regular expressions. In ASCII order, the range expression [A-Z] stands for the 26 upper-case letters. That is because the expression stands for the characters starting with A and ending with Z. In ASCII, the upper-case letters form a contiguous block of 26 running from A to Z. However, in the French locale the letters starting with A and ending with Z consist of all of the letters except for lower-case a.

The format of times and dates is controlled by LC_TIME. In American English, the date command produces results like this:

Fri Apr 14 20:33:28 PDT 2006

In Catalan, the language is different but the format is the same:

dv abr 14 20:33:49 PDT 2006

But in Japanese the year comes first, then the month, then the day, then the day of the week, and finally the time:

2006年 4月 14日 金曜日 20:34:42 PDT

The format of numbers is determined by LC_NUMERIC. In American English, a period serves as decimal point and commas break the integers into groups of three:

652,314,159.278

In German, the grouping is the same but the roles of period and comma are reversed:

652.314.159,278

In Hindi the period and comma play the same roles as in American English, but the integers are broken into groups of two, except for the hundreds downward, which form a group of three:

65,23,14,159.278

The format of amounts of money is controlled by LC_MONETARY. In addition to the formatting of the numbers, this environment variable specifies the symbol for the unit of currency and things like how negative values are written.

Additional variables include:

  • LC_PAPER: paper size
  • LC_NAME: personal name format
  • LC_ADDRESS: address format
  • LC_TELEPHONE: telephone number format
  • LC_MEASUREMENT: measurement units

The environment variable hierarchy

Most of the time you'll want to set all of these variables to the same value, but occasionally it makes sense to use different values. For example, if you want your interface language to be English but are sorting French data, you could set LC_MESSAGES to en_US but LC_COLLATE to fr_FR.

When you don't want to use different values, it isn't necessary to set all of the variables individually. Instead, you can set LC_ALL or LANG. When a program looks at the environment variables to determine what locale to use, it follows the following procedure:

  1. If the LC_ALL environment variable is defined and is not null, its value is used.
  2. If the appropriate component-specific environment variable -- e.g. LC_COLLATE -- is set and non-null, its value is used.
  3. If the LANG environment variable is defined and is not null, its value is used.
  4. If the LANG environment variable is not set or is null, an implementation-dependent default locale is used.

Notice that this means that if you want to use different locales for different purposes you should unset LC_ALL.

There is one further environment variable, LANGUAGE, which is used only by GNU gettext, the system that provides translations of messages for many programs. Unlike the others, this variable can be assigned multiple locales separated by colons. The locales are tried in order until a message catalog is found. For example, the specification sv_SE:nn_NO:de_DE indicates that the user prefers Swedish, to use Norwegian if Swedish is not available, and to use German if Norwegian is not available. If defined, LANGUAGE takes precedence over LC_ALL, LC_MESSAGES, and LANG.

Locale names

Locale names take the form:

language(_territory)(.encoding)(@modifier)

The only obligatory part is the language code, such as en for English. The same language may be used in different ways in different countries, so locale names commonly include a territory code as second component. Thus, fr_FR is the locale for French in France, fr_CA for French in Canada, and en_CA the locale for English in Canada. An encoding may also be specified. English will by default be encoded in ASCII, but en_US.UTF-8 specifies American English in the UTF-8 Unicode encoding. Language codes are usually taken from the list of two-letter codes defined in ISO-639-1, country codes from the two-letter codes defined in ISO-3166-1.

The modifier you are most likely to see is euro, which is used for locales using the euro currency where the original locale definition was created before the introduction of the euro in the European Union. For example, es_ES@euro is the current Spanish locale, while es_ES is the pre-euro locale.

A few special locales do not follow these naming conventions. The POSIX locale, also known as the C locale, sets up a traditional Unix environment, with the ASCII encoding, POSIX character classes, and American English time, date, number, and monetary formats. If things seem off when you use programs such as sort and grep, the problem may be that you are using a locale that defines a different sort order or character classes from what you are used to. Setting your locale to POSIX may set things right.

To find out what your current locale is, use the locale command with no arguments. It will print the values of all of the relevant environment variables except for LANGUAGE. locale charmap prints the name of the current encoding. To find out what locales are available, type locale -a. To find out what encodings are available, type locale -m.

Installing locales

You may find that the locale you need is not installed on your machine. If so, you may be able to install it yourself. Locale definitions are stored in plain ASCII files that follow a special format described in the locale(5) man page. How to write your own locale definitions would be fodder for a whole other article, but you can find quite a few locale definitions in localedata/locales in the glibc distribution directory, in files whose names are the same as the locale name, e.g. zu_ZA for Zulu in South Africa.

To install a locale file, use localedef. This command installs Zulu:

localedef -i zu_ZA -f ../charmaps/UTF-8 zu_ZA

The last argument here is the locale name. The argument to the -i flag is the locale definition file. The argument to the -f flag is the appropriate character set definition file, most frequently UTF-8.

Looking forward

Many languages do not have a two-letter code, so three-letter codes from ISO-639-2 are increasingly seeing use. Similarly, three-letter country codes defined in ISO-3166-2 are on the horizon.

Another development is the Common Locale Data Repository project sponsored by the Unicode Consortium. Recognizing that it is inefficient for different operating systems and developers to compile localization information and store it in different formats, the CLDR project is developing a new, XML-based, cross-platform system for storing locale information which is already in use by Java and some other programs.

2007-07-05

[gcc] -rdynamic

> BTW, why is it that the -soname option and the -rdynamic
> option are not in the man page for gcc?

Essentially because they are really linker options, passed by gcc down to
ld. This is strictly true for -soname: the comma-separated list
following -Wl option of gcc is passed directly to the linker, after
replacing the commas with spaces (you can see this if you gcc -v). No
other processing is done on it by the compiler proper.

The -rdynamic option is slightly different. It seems to have been
introduced as a high-level interface to the linker, to (a) force the
allocation of a global symbol table in the final executable, even if it's
not strictly needed, and (b) cause the inclusion of the global symbols in
that symbol table.

  • Under linux, gcc interprets it by setting the "-export-dynamic" option for ld, which has that effect, according to the linux ld manpage.
  • Under IRIX it's ignored, and the program's happy as a clam.
  • Under SunOS-4.1, gcc interprets it by setting the -dc -dp options for ld, which again forces the allocation of the symbol table in the code produced (see ld(1) on a Sun).

Wonder if we should mailbomb gcc-bug@gnu.org until they fix their man/info
pages ;-)

-- From http://www.cim.mcgill.ca/~franco/OpSys-304-427/messages/node59.html

Hacking HelloWorld

HackingHelloWorld (PDF)

- From Jim Huang (黃敬群 / jserv)

[Keywords: hello world]

修改常量字符串导致的 segmentation fault

昨天一同事遇到的问题, 帮他解决了一下, 备忘 :-)


$ cat foo.c
#include

int main(int argc, char *argv[])
{
char *s = "foo;bar;car";

strtok(s, ";");

return 0;
}
$ gcc foo.c
$ ./a.out
Segmentation fault
$ gcc -S foo.c
$ cat foo.s
.file "foo.c"
.section .rodata ; read only data (?)
.LC0:
.string "foo;bar;car"
.LC1:
.string ";"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
subl %eax, %esp
movl $.LC0, -4(%ebp)
movl $.LC1, 4(%esp)
movl -4(%ebp), %eax
movl %eax, (%esp)
call strtok
movl $0, %eax
leave
ret
.size main, .-main
.ident "GCC: (GNU) 4.0.3 (Ubuntu 4.0.3-1ubuntu5)"
.section .note.GNU-stack,"",@progbits
$

svn: Not authorised to open root of edit operation

如果启用了 svn 的 path-based access control, svnserve.conf 中的 anon-access 要设成 none 才行:

$ cat svnserve.conf
[general]
anon-access = none
auth-access = write
password-db = passwd
authz-db = authz
realm = My Realm
$ cat authz
[/]
admin = rw

[/project1]
guest = r
$

2007-07-04

[bash] New cool prompt

crypt(): DES or MD5

DES 算法的 crypt() 函数最多只支持 8 个字符的 password, 超过 8 个字符的部分被忽略掉了; 而 MD5 算法的 crypt() 则没有这个限制. 因此现在的 passwd 命令一般用 MD5 加密方式.

From crypt's man page:
=====================
The glibc2 version of this function has the following additional features. If salt is a character string starting with the three characters "$1$" followed by at most eight characters, and optionally terminated by "$", then instead of using the DES machine, the glibc crypt function uses an MD5-based algorithm, and outputs up to 34 bytes, namely "$1$$", where "" stands for the up to 8 characters following "$1$" in the salt, followed by 22 bytes chosen from the set [a-zA-Z0-9./]. The entire key is significant here (instead of only the first 8 bytes).

MacPorts: Installed ports

autoconf
automake
bash
cmake
colordiff
expect
findutils
gawk
gnutar
gsed
lftp
libtool
subversion
tcl
vim
watch
wget
wireshark

Bash: COLUMNS and LINES not set on startup

Mac OS X (10.4) 上默认安装的 bash 还是经典的 2.05b 版, 不如 3.x 强大. 自己下载编译了 3.2.17 编译安装, 一切顺利. 但是启动 bash 3.2.17 后发现 COLUMNS 和 LINES 这两个变量没有定义, 不过在改变终端窗口大小后就有定义了, 有些麻烦, 只好在 bashrc 里面给 bash 发一个 SIGWINCH 信号:

$ kill -s SIGWINCH $$

2007-07-01

MacPorts: The port command

  • port selfupdate
  • port search subversion
  • port install bash
  • port variants vim
  • port install vim +perl +cscope subversion +no_bdb
  • port cat vim
  • port deactivate vim @7.1.002_0
  • port upgrade vim
  • port upgrade installed
  • port info bash
  • port deps subversion
  • port dependents readline
  • port outdated
  • ... ...