從零開始UNIX環(huán)境高級編程(6):系統(tǒng)數(shù)據(jù)文件和信息

0. 思維導(dǎo)圖

系統(tǒng)數(shù)據(jù)文件和信息

1. 口令文件

從零開始UNIX環(huán)境高級編程(1)中,已經(jīng)介紹過口令文件(/etc/passwd),本小節(jié)主要學(xué)習(xí)如果通過函數(shù)去獲取口令文件的信息。

1.1 passed結(jié)構(gòu)體

存放口令文件信息的結(jié)構(gòu)體為passed,定義在pwd.h中,不同平臺實現(xiàn)的字段也會不一樣

  • Mac OS X中passwd結(jié)構(gòu)體

      struct passwd {
              char    *pw_name;               /* user name */
              char    *pw_passwd;             /* encrypted password */
              uid_t   pw_uid;                 /* user uid */
              gid_t   pw_gid;                 /* user gid */
              __darwin_time_t pw_change;              /* password change time */
              char    *pw_class;              /* user access class */
              char    *pw_gecos;              /* Honeywell login info */
              char    *pw_dir;                /* home directory */
              char    *pw_shell;              /* default shell */
              __darwin_time_t pw_expire;              /* account expiration */
      };
    
  • Ubuntu中passwd結(jié)構(gòu)體

         struct passwd {
             char   *pw_name;       /* username */
             char   *pw_passwd;     /* user password */
             uid_t   pw_uid;        /* user ID */
             gid_t   pw_gid;        /* group ID */
             char   *pw_gecos;      /* user information */
             char   *pw_dir;        /* home directory */
             char   *pw_shell;      /* shell program */
         };
    

1. 2 獲取passwd

1.2.1 獲取單個用戶信息

獲取passwd中單個用戶信息的函數(shù)有兩個:使用getpwnam獲取用戶信息時轧坎,需要傳入該用戶的名稱作為參數(shù);使用getpwuid獲取用戶信息時泽示,需要傳入該用戶的id作為參數(shù)缸血。

   struct passwd *getpwnam(const char *name);
   struct passwd *getpwuid(uid_t uid);
  • 示例代碼

    以getpwnam函數(shù)為例蜜氨,看下如何獲取單個用戶信息

#include "apue.h"
#include <pwd.h>

int main(int argc, char const *argv[])
{
    struct  passwd * info;
    info = getpwnam("ckt");
    if (info == NULL) {
        printf("get passwd fail\n");
        return 0;
    }
    printf("pw_uid = %d   pw_gid = %d   pw_gecos = %s   pw_dir = %s   pw_shell = %s \n"
        , info->pw_uid, info->pw_gid, info->pw_gecos , info->pw_dir , info->pw_shell);
    return 0;
}
  • 運行結(jié)果

    使用getpwnam函數(shù)獲取到的信息和/etc/passwd中存放的信息一致

ckt@ubuntu:~/work/unix/code/chapter6$ ./passwdinfo_test
pw_uid = 1000   pw_gid = 1000   pw_gecos = ckt,,,   pw_dir = /home/ckt   pw_shell = /bin/bash 

ckt@ubuntu:~/work/unix/code/chapter6$ cat /etc/passwd | grep ckt
ckt:x:1000:1000:ckt,,,:/home/ckt:/bin/bash

1.2.2 遍歷整個口令文件

上面兩個函數(shù)只能獲取單個用戶信息,如果要得到整個口令文件捎泻,需要用到下面3個函數(shù)飒炎,而getpwnam和getpwuid中也會對這3個函數(shù)進行封裝。

   struct passwd *getpwent(void);

   void setpwent(void);

   void endpwent(void);
  • 示例代碼
    自定義一個getpwuid函數(shù)名為my_getpwuid笆豁,里面會調(diào)用到setpwent郎汪、getpwent、endpwent這3個函數(shù)
#include "apue.h"
#include <pwd.h>

struct passwd *my_getpwuid(uid_t uid)
{
    struct passwd * ptr;

    setpwent();

    while((ptr = getpwent()) != NULL)
        if (ptr->pw_uid == uid)
            break;

    endpwent();

    return ptr;
}

int main(int argc, char const *argv[])
{
    struct  passwd * info;
    info = my_getpwuid(1000);
    if (info == NULL) {
        printf("get passwd fail\n");
        return 0;
    }
    printf("pw_name = %s   pw_gid = %d   pw_gecos = %s   pw_dir = %s   pw_shell = %s \n"
        , info->pw_name, info->pw_gid, info->pw_gecos , info->pw_dir , info->pw_shell);
    return 0;
}
  • 運行結(jié)果
ckt@ubuntu:~/work/unix/code/chapter6$ cc myget_passwdinfo.c -o myget_passwdinfo
ckt@ubuntu:~/work/unix/code/chapter6$ ./myget_passwdinfo
pw_name = ckt   pw_gid = 1000   pw_gecos = ckt,,,   pw_dir = /home/ckt   pw_shell = /bin/bash 

ckt@ubuntu:~/work/unix/code/chapter6$ cat /etc/passwd | grep 1000
ckt:x:1000:1000:ckt,,,:/home/ckt:/bin/bash

2. 陰影文件

系統(tǒng)將登陸密碼進行加密闯狱,并將加密后的口令存放在陰影文件/etc/shadow中煞赢,查看陰影文件需要root權(quán)限

ckt@ubuntu:~/work/unix/code/chapter6$ sudo cat /etc/shadow | grep ckt
ckt:$1$6BZmOQTp$RV1GboT5SxQR1hV3ZauQ..:16401:0:99999:7:::

2.1 spwd結(jié)構(gòu)體

和口令文件一樣,陰影文件也有對應(yīng)的結(jié)構(gòu)體spwd哄孤,spwd結(jié)構(gòu)體定義在 <shadow.h> 中

       struct spwd {
           char *sp_namp;     /* Login name */
           char *sp_pwdp;     /* Encrypted password */
           long  sp_lstchg;   /* Date of last change (measured
                                 in days since 1970-01-01 00:00:00 +0000 (UTC)) */
           long  sp_min;      /* Min # of days between changes */
           long  sp_max;      /* Max # of days between changes */
           long  sp_warn;     /* # of days before password expires
                                 to warn user to change it */
           long  sp_inact;    /* # of days after password expires
                                 until account is disabled */
           long  sp_expire;   /* Date when account expires (measured
                                 in days since 1970-01-01 00:00:00 +0000 (UTC)) */
           unsigned long sp_flag;  /* Reserved */
       };

2.2 獲取spwd結(jié)構(gòu)體函數(shù)

   // 通過用戶名稱獲取單個用戶的spwd信息
   struct spwd *getspnam(const char *name);

   //以下三個函數(shù)用戶獲取整個/etc/shadow信息
   struct spwd *getspent(void);

   void setspent(void);

   void endspent(void);
  • 示例代碼
#include "apue.h"
#include <shadow.h>

int main(int argc, char const *argv[])
{
    struct  spwd * info;
    info = getspnam("ckt");
    if (info == NULL) {
        printf("get passwd fail\n");
        return 0;
    }
    printf("sp_pwdp = %s   sp_lstchg = %ld   sp_min = %ld   sp_max = %ld   sp_warn = %ld\
        sp_inact = %ld  sp_expire = %ld  sp_flag = %ld \n", info->sp_pwdp, info->sp_lstchg,
        info->sp_min , info->sp_max , info->sp_warn , info->sp_inact , info->sp_expire , info->sp_flag);
    return 0;
}
  • 運行結(jié)果
ckt@ubuntu:~/work/unix/code/chapter6$ sudo ./shadowinfo_test
sp_pwdp = $1$6BZmOQTp$RV1GboT5SxQR1hV3ZauQ..   sp_lstchg = 16401   sp_min = 0   sp_max = 99999   sp_warn = 7        sp_inact = -1  sp_expire = -1  sp_flag = -1 
ckt@ubuntu:~/work/unix/code/chapter6$ sudo cat /etc/shadow | grep ckt
ckt:$1$6BZmOQTp$RV1GboT5SxQR1hV3ZauQ..:16401:0:99999:7:::

3. 組文件

組文件/etc/group用來存放系統(tǒng)中所有的group信息
/etc/group文件格式:group_name:password:GID:user_list

ckt@ubuntu:~/work/unix/code/chapter6$ cat /etc/group | grep ckt
ckt:x:1000:

3.1 group結(jié)構(gòu)體

group結(jié)構(gòu)體定義在<grp.h>

   struct group {
       char   *gr_name;       /* group name */
       char   *gr_passwd;     /* group password */
       gid_t   gr_gid;        /* group ID */
       char  **gr_mem;        /* group members */
   };

3.2 獲取group函數(shù)

   //通過組名稱獲取當個group信息
   struct group *getgrnam(const char *name);
   //通過組ID獲取當個group信息
   struct group *getgrgid(gid_t gid);

   //使用以下3個函數(shù)照筑,獲取整個/etc/group信息
   struct group *getgrent(void);

   void setgrent(void);

   void endgrent(void);
  • 示例代碼
#include "apue.h"
#include <grp.h>

int main(int argc, char const *argv[])
{
    struct group * info;
    info = getgrnam("zhm");
    if (info == NULL) {
        printf("get group fail\n");
        return 0;
    }

    printf("gr_name = %s  gr_passwd = %s  gr_gid = %d  gr_mem = %s \n", 
        info->gr_name, info->gr_passwd, info->gr_gid, *info->gr_mem);
    return 0;
}
  • 運行結(jié)果
ckt@ubuntu:~/work/unix/code/chapter6$ cc groupinfo_test.c -o groupinfo_test
ckt@ubuntu:~/work/unix/code/chapter6$ ./groupinfo_test
gr_name = zhm  gr_passwd = x  gqr_gid = 1001  gr_mem = ckt 
ckt@ubuntu:~/work/unix/code/chapter6$ cat /etc/group | grep zhm
zhm:x:1001:ckt

4. 附屬組

一個用戶可以屬于多個組,通過id命令可以查看用戶的主組和附屬組

ckt@ubuntu:~/work/code/mt6737$ id ckt
uid=1000(ckt) gid=1000(ckt) groups=1000(ckt),1001(zhm)

4.1 getgroups函數(shù)

使用getgroups函數(shù)瘦陈,可以獲取進程所屬用戶的主組和附屬組ID

int getgroups(int size, gid_t list[]);
  • 示例代碼
#include "apue.h"
#include <sys/types.h>
#include <unistd.h>

#define MAX_GROUP_SIZE 5

int main(int argc, char const *argv[])
{
    int i = 0, group_size = 0;
    int group_list[MAX_GROUP_SIZE];

    if ((group_size = getgroups(MAX_GROUP_SIZE, group_list)) > 0)
    {
        for (i = 0; i < group_size; i++)
        {
            printf("group_list[%d] : %d \n", i , group_list[i]);
        }
    }
    else 
        printf("get groups fail\n");

    return 0;
}
  • 運行結(jié)果

分別獲取用戶ckt和root的主組ID和附屬組ID凝危,和使用命令id得到的結(jié)果一致

ckt@ubuntu:~/work/unix/code/chapter6$ cc getgroups_test.c -o getgroups_test
ckt@ubuntu:~/work/unix/code/chapter6$ ./getgroups_test
group_list[0] : 1000 
group_list[1] : 1001 
ckt@ubuntu:~/work/unix/code/chapter6$ sudo ./getgroups_test
group_list[0] : 0 

ckt@ubuntu:~/work/unix/code/chapter6$ id ckt
uid=1000(ckt) gid=1000(ckt) groups=1000(ckt),1001(zhm)
ckt@ubuntu:~/work/unix/code/chapter6$ id root
uid=0(root) gid=0(root) groups=0(root)

5. 其他數(shù)據(jù)文件

除了上面介紹的一些文件,系統(tǒng)中還有很多其他類型的數(shù)據(jù)文件晨逝,它們的操作方式都是類似的蛾默。各個數(shù)據(jù)的文件名稱、結(jié)構(gòu)體和操作函數(shù)捉貌,如下表:

系統(tǒng)數(shù)據(jù)文件

6. 登錄賬戶記錄

utmp文件(/var/run/utmp)記錄當前登錄到系統(tǒng)的各個用戶支鸡;wtmp文件(/var/log/wtmp)跟蹤各個登錄和注銷事件

我們可以使用who命令讀取utmp文件,使用last命令讀取wtmp文件

ckt@ubuntu:~/work/unix/code/chapter6$ who
ckt      tty7         2017-03-02 17:00
ckt      pts/0        2017-03-02 18:04 (:0)
ckt      pts/1        2017-03-02 20:58 (:0)
ckt      pts/2        2017-03-02 21:37 (:0)

ckt@ubuntu:~/work/unix/code/chapter6$ last
ckt      pts/2        :0               Thu Mar  2 21:37   still logged in   
ckt      pts/1        :0               Thu Mar  2 20:58   still logged in   
ckt      pts/0        :0               Thu Mar  2 18:04   still logged in   
reboot   system boot  3.13.0-32-generi Thu Mar  2 16:58 - 00:26  (07:28)    
ckt      pts/2        :0               Thu Mar  2 03:19 - 03:45  (00:26)    
ckt      pts/1        :0               Thu Mar  2 00:46 - 03:19  (02:33)    
ckt      pts/1        :0               Thu Mar  2 00:40 - 00:40  (00:00)    
ckt      pts/0        :0               Thu Mar  2 00:17 - 03:45  (03:28)    
reboot   system boot  3.13.0-32-generi Thu Mar  2 00:16 - 03:45  (03:29)    
ckt      pts/1        :0               Thu Mar  2 00:08 - crash  (00:07)    

7. 系統(tǒng)標識

使用uname命令可以查看操作系統(tǒng)有關(guān)信息昏翰,同樣我們也可以通過函數(shù)去獲取這些信息苍匆。

ckt@ubuntu:~/work/unix/code/chapter6$ uname -a
Linux ubuntu 3.13.0-32-generic #57~precise1-Ubuntu SMP Tue Jul 15 03:51:20 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

使用hostname命令可以獲取主機名

ckt@ubuntu:~/work/unix/code/chapter6$ hostname 
ubuntu

7.1 uname結(jié)構(gòu)體

uname結(jié)構(gòu)體用來存放操作系統(tǒng)有關(guān)信息刘急,定義在#include <sys/utsname.h>

   struct utsname {
       char sysname[];    /* Operating system name (e.g., "Linux") */
       char nodename[];   /* Name within "some implementation-defined
                             network" */
       char release[];    /* OS release (e.g., "2.6.28") */
       char version[];    /* OS version */
       char machine[];    /* Hardware identifier */
   #ifdef _GNU_SOURCE
       char domainname[]; /* NIS or YP domain name */
   #endif
   };

7.2 uname函數(shù)

通過uname函數(shù)獲取信息并返回這些值到buf中

int uname(struct utsname *buf);
  • 示例代碼
#include "apue.h"
#include <sys/utsname.h>

int main(int argc, char const *argv[])
{
    struct utsname info;
    if (uname(&info) == -1)
    {
        printf("get uname fail\n");
        return 0;
    }

    printf("%s %s %s %s %s", info.sysname, info.nodename, info.release, info.version, info.machine);

#ifdef _GNU_SOURCE
    printf(" %s", info.domainname);
#endif

    printf("\n");

    return 0;
}
  • 運行結(jié)果
ckt@ubuntu:~/work/unix/code/chapter6$ cc getuname_test.c -o getuname_test
ckt@ubuntu:~/work/unix/code/chapter6$ ./getuname_test
Linux ubuntu 3.13.0-32-generic #57~precise1-Ubuntu SMP Tue Jul 15 03:51:20 UTC 2014 x86_64

ckt@ubuntu:~/work/unix/code/chapter6$ uname -a
Linux ubuntu 3.13.0-32-generic #57~precise1-Ubuntu SMP Tue Jul 15 03:51:20 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

7.3 gethostname函數(shù)

 int gethostname(char *name, size_t len);
  • 示例代碼
#include "apue.h"
#include <limits.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
    char hostname[HOST_NAME_MAX];
    int i = 0;

    if (gethostname(hostname, HOST_NAME_MAX) == -1)
        printf("get hostname fail\n");

    while(hostname[i] != '\0')
    {
        printf("%c", hostname[i]);
        i++;
    }
    printf("\n");
    return 0;
}
  • 運行結(jié)果
ckt@ubuntu:~/work/unix/code/chapter6$ cc gethostname_test.c -o gethostname_test
ckt@ubuntu:~/work/unix/code/chapter6$ ./gethostname_test
ubuntu
ckt@ubuntu:~/work/unix/code/chapter6$ hostname 
ubuntu

8. 時間和日期歷程

各個函數(shù)直接的關(guān)系

8.1 獲取UTC時間

8.1.1 time函數(shù)

time函數(shù)定義在<time.h>中棚菊,用來獲取UTC時間

time_t time(time_t *t);

8.1.2 clock_gettime函數(shù)

當clk_id設(shè)置為CLOCK_REALTIME時,clock_gettime的功能和time類似叔汁,在系統(tǒng)支持高精度時間值的情況下统求, clock_gettime可能比time函數(shù)得到更高精度的時間值

int clock_gettime(clockid_t clk_id, struct timespec *tp);
  • clk_id參數(shù)說明
標識符 說明
CLOCK_REALTIME 實時系統(tǒng)時間
CLOCK_MONOTONIC 不帶負跳數(shù)的實時系統(tǒng)時間
CLOCK_PROCESS_CPUTIME_ID 調(diào)用進程的CPU時間
CLOCK_THREAD_CPUTIME_ID 調(diào)用線程的CPU時間
  • timespec結(jié)構(gòu)體
    struct timespec {
           time_t   tv_sec;        /* seconds */
           long     tv_nsec;       /* nanoseconds */
       };

8.1.3 gettimeofday函數(shù)

和time函數(shù)功能類似,gettimeofday提供了更高的精度(微秒級)

int gettimeofday(struct timeval *tv, struct timezone *tz);
  • timeval結(jié)構(gòu)體
struct timeval {
           time_t      tv_sec;     /* seconds */
           suseconds_t tv_usec;    /* microseconds */
       };

8.2 將日歷時間轉(zhuǎn)換成分解的時間

調(diào)用gmtime和localtime函數(shù)可以將time_t格式的UTC時間轉(zhuǎn)換成分解的時間据块,存放在tm結(jié)構(gòu)體中

   struct tm *gmtime(const time_t *timep);
   struct tm *localtime(const time_t *timep);

   struct tm {
       int tm_sec;         /* seconds */
       int tm_min;         /* minutes */
       int tm_hour;        /* hours */
       int tm_mday;        /* day of the month */
       int tm_mon;         /* month */
       int tm_year;        /* year */
       int tm_wday;        /* day of the week */
       int tm_yday;        /* day in the year */
       int tm_isdst;       /* daylight saving time */
   };

8.3 格式化輸出時間

調(diào)用strftime將tm格式的時間值格式化輸出码邻,strftime需要通過TZ環(huán)境變量指定時區(qū)

 size_t strftime(char *s, size_t max, const char *format,
                   const struct tm *tm);
  • TZ環(huán)境變量

TZ環(huán)境變量用來設(shè)置時區(qū),設(shè)置方法如下:

ckt@ubuntu:~$ export TZ=Asia/Shanghai
ckt@ubuntu:~$ date
Tue Mar  7 09:15:24 CST 2017
ckt@ubuntu:~$ export TZ=Asia/Tokyo
ckt@ubuntu:~$ date
Tue Mar  7 10:15:46 JST 2017

8.4 示例代碼

#include "apue.h"
#include <time.h>

int main(int argc, char const *argv[])
{
    time_t t;
    struct tm *tmp = NULL;
    char buf1[64];

    if (time(&t) == -1)
    {
        printf("get time error\n");
        return 0;
    }

    tmp = localtime(&t);

    if (tmp == NULL)
    {
        printf("get localtime error\n");
        return 0;
    }

    if (strftime(buf1, 64, "time and date : %r, %a %b %d, %Y", tmp) == 0)
        printf("buffer len 64 is too small\n");
    else
        printf("%s\n", buf1);

    return 0;
}
  • 運行結(jié)果
ckt@ubuntu:~/work/unix/code/chapter6$ cc getdate_test.c -o getdate_test
ckt@ubuntu:~/work/unix/code/chapter6$ ./getdate_test
time and date : 11:00:08 PM, Wed Mar 08, 2017

參考

  • UNIX 環(huán)境高級編程 第3版
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末另假,一起剝皮案震驚了整個濱河市像屋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌边篮,老刑警劉巖己莺,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奏甫,死亡現(xiàn)場離奇詭異,居然都是意外死亡凌受,警方通過查閱死者的電腦和手機阵子,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胜蛉,“玉大人挠进,你說我怎么就攤上這事√懿幔” “怎么了领突?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長解虱。 經(jīng)常有香客問我攘须,道長,這世上最難降的妖魔是什么殴泰? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任于宙,我火速辦了婚禮,結(jié)果婚禮上悍汛,老公的妹妹穿的比我還像新娘捞魁。我一直安慰自己,他們只是感情好离咐,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布谱俭。 她就那樣靜靜地躺著,像睡著了一般宵蛀。 火紅的嫁衣襯著肌膚如雪昆著。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天术陶,我揣著相機與錄音凑懂,去河邊找鬼。 笑死梧宫,一個胖子當著我的面吹牛接谨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播塘匣,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼脓豪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了忌卤?” 一聲冷哼從身側(cè)響起扫夜,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后笤闯,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體现拒,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年望侈,在試婚紗的時候發(fā)現(xiàn)自己被綠了印蔬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡脱衙,死狀恐怖侥猬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情捐韩,我是刑警寧澤退唠,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站荤胁,受9級特大地震影響瞧预,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仅政,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一垢油、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧圆丹,春花似錦滩愁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至倦微,卻和暖如春妻味,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背欣福。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工责球, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人劣欢。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓棕诵,卻偏偏與公主長得像裁良,于是被迫代替她去往敵國和親凿将。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容