回精華區
作者shakalaca.bbs@bittern.csie.nctu.edu.tw.bbs@aurora. 看板: plan
標題[doc] bbs + gallery
時間aurora (2004/03/08 Mon 19:07:12) Updated: 2004/04/28
: so/Makefile 若是 FreeBSD 這樣改

SO =    .... gallery.so

.SUFFIXES:
.SUFFIXES: .c .o .so

.c.o:   ;  $(CC) $(CFLAGS) -c $*.c
.o.so:  ;  ld -s -G $*.o -o $*.so -L../lib -ldao -lmd

: so/Makefile 若是 Linux 這樣改

SO =    .... gallery.so

SUFFIXES:
SUFFIXES: .c .o .so

c.o:    ;  $(CC) $(CFLAGS) -c $*.c
o.so:   ;  ld -s -G $*.o -o $*.so -L../lib -ldao -lssl

: menu.c 適當的選單加入

  "bin/gallery.so:create_account", 0, - M_XMODE,
  "Gallery    ♂ 新增相簿 ♀",

: so/gallery.c 新增此程式

/*-------------------------------------------------------*/
/* gallery.c    ( NTHU CS MapleBBS Ver 2.36 )            */
/*-------------------------------------------------------*/
/* target : create gallery account                       */
/* create : 04/03/08                                     */
/* update : 04/03/08                                     */
/* author : shakalaca.bbs@php.twbbs.org                  */
/*-------------------------------------------------------*/


#include "bbs.h"


#define ALBUM_PATH      "/home/data/www/albums"
#define FN_GALLERY_LOG  "run/gallery.log"


typedef struct
{
  char username[32];
  char fullname[32];
  char password[64];
  char email[64];
  char uid[32];
  char lastactiondate[64];
} GalleryUser;


/* ------------------------------------------------------------------ */

static void
f_add(fpath, msg)   /* 仿 f_cat(),唯權限改為 0664 */
  char *fpath;
  char *msg;
{
  int fd;

  if ((fd = open(fpath, O_WRONLY | O_CREAT | O_APPEND, 0664)) >= 0)
  {
    write(fd, msg, strlen(msg));
    close(fd);
  }
}


static void
f_join(from, to)    /* 效果類似 f_suck(),唯權限改為 0664 */
  char *from, *to;
{
  int in, out, len;
  char buf[512];

  if ((in = open(from, O_RDONLY)) >= 0)
  {
    if ((out = open(to, O_WRONLY | O_CREAT | O_APPEND, 0664)) >= 0)
    {
      while (len = read(in, buf, sizeof(buf)))
        write(out, buf, len);

      close(out);
    }
    close(in);
  }
}


/* ------------------------------------------------------------------ */


static int      /* 1:成功 0:失敗 */
create_file(u, hash)
  GalleryUser u;
  char *hash;
{
  char fpath[64], input[1024];

  sprintf(fpath, "%s/.users/%s", ALBUM_PATH, hash);

  if (!dashf(fpath))     /* 要檢查 hash 是不是有重覆 */
  {
    sprintf(input, "O:12:\"gallery_user\":13:{s:8:\"username\";%s;"
      "s:8:\"fullname\";%s;s:8:\"password\";%s;s:5:\"email\";%s;s:7:\"isAdmin\";b:0;"
      "s:15:\"canCreateAlbums\";s:1:\"0\";s:3:\"uid\";%s;s:15:\"defaultLanguage\";"
      "s:5:\"en_US\";s:7:\"version\";i:5;s:15:\"recoverPassHash\";N;"
      "s:10:\"lastAction\";s:8:\"register\";s:14:\"lastActionDate\";%s;"
      "s:9:\"origEmail\";%s;}",
      u.username, u.fullname, u.password, u.email, u.uid,
      u.lastactiondate, u.email);

    f_add(fpath, input);
    return 1;
  }

  return 0;
}


static int      /* 1:成功 0:失敗 */
create_album(u, hash)
  GalleryUser u;
  char *hash;
{
  char fpath[128], file[128], buf[256], buf2[128];
  time_t now;

  sprintf(fpath, "%s/%s", ALBUM_PATH, cuser.userid);

  if (!dashd(fpath))
  {
    if (mkdir(fpath, 0775) == -1)
    {
      /* 要把剛才產生的 hashfile 刪除 */
      sprintf(fpath, "%s/.users/%s", ALBUM_PATH, hash);
      unlink(fpath);
      return 0;
    }

    time(&now);

    sprintf(file, "%s/photos.dat", fpath);
    f_add(file, "N;");

    sprintf(file, "%s/album.dat", fpath);

    sprintf(buf2, "%s 的相簿", cuser.userid);
    sprintf(buf, "O:5:\"album\":5:{s:6:\"fields\";a:57:{s:5:\"title\";s:%d:\"%s\";",
      strlen(buf2), buf2);
    f_add(file, buf);

    f_join("etc/gallery/album.dat.head", file);

    sprintf(buf, "s:11:\"clicks_date\";i:%ld;", now);
    f_add(file, buf);

    f_join("etc/gallery/album.dat.body", file);

    sprintf(buf, "s:4:\"name\";s:%d:\"%s\";s:5:\"owner\";%s;s:13:\"last_mod_time\";i:%ld;",
      strlen(cuser.userid), cuser.userid, u.uid, now);
    f_add(file, buf);

    f_join("etc/gallery/album.dat.foot", file);
  }

  return 1;
}


#ifdef LINUX

#include <openssl/md5.h>

static char *
gen_salt(password)
  char *password;
{
#define MD5ENCODELEN    16
  int i;
  MD5_CTX ctx;
  char buf[MD5ENCODELEN];
  static char retbuf[2 * MD5ENCODELEN + 1];

  MD5Init(&ctx);
  MD5Update(&ctx, (uschar *) password, (usint) strlen(password));
  MD5Final(buf, &ctx);

  for (i = 0; i < MD5ENCODELEN; i++)
    sprintf(retbuf + (i << 1), "%02x", buf[i]);

  return retbuf;
}

#else

#include <md5.h>

static char *
gen_salt(password)        /* 輸入原始密碼,輸出加密密碼 */
  char *password;
{
  int i, ch;
  char salt[5], tmpbuf[64], buf[33];
  static char retbuf[64];

  for (i = 0; i < 4; i++)
  {
    ch = rand() % (109 - 48 + 1) + 48;
    if (ch > 57)
      ch += 7;
    if (ch > 90)
      ch += 6;
    salt[i] = ch;
  }
  salt[4] = '\0';

  sprintf(tmpbuf, "%s%s", salt, password);
  MD5Data(tmpbuf, strlen(tmpbuf), buf);
  sprintf(retbuf, "%s%s", salt, buf);

  return retbuf;
}
#endif


static void
gallery_log(mode)
  char *mode;
{
  char buf[128];

  sprintf(buf, "%s %s (%s)\n", Now(), mode, cuser.userid);

  f_add(FN_GALLERY_LOG, buf);
}


int
create_account()
{
  GalleryUser gu;
  char buf[128], *ptr;
  time_t now;

  sprintf(buf, "%s/%s", ALBUM_PATH, cuser.userid);

  if (dashd(buf))
  {
    vmsg("您已經申請過相簿了!");
    return XEASY;
  }

  time(&now);
  sprintf(gu.username, "s:%d:\"%s\"", strlen(cuser.userid), cuser.userid);
  sprintf(gu.fullname, "s:%d:\"%s\"", strlen(cuser.username), cuser.username);
  sprintf(gu.email, "s:%d:\"%s\"", strlen(cuser.email), cuser.email);
  sprintf(gu.lastactiondate, "i:%ld", now);

  for (;;)
  {
    vget(b_lines, 0, "請設定密碼:", buf, PSWDLEN + 1, NOECHO);
    if ((strlen(buf) < 3) || !strcmp(buf, cuser.userid))
    {
      vmsg("密碼太簡單,易遭入侵,至少要 4 個字,請重新輸入");
      continue;
    }

    vget(b_lines, 0, "請檢查密碼:", buf + PSWDLEN + 2, PSWDLEN + 1, NOECHO);
    if (!strcmp(buf, buf + PSWDLEN + 2))
      break;

    vmsg("密碼輸入錯誤, 請重新輸入密碼");
  }

  srand(now + cuser.userno);
  ptr = gen_salt(buf);
  sprintf(gu.password, "s:%d:\"%s\"", strlen(ptr), ptr);

  /* 確保同一時間不同人建的 hash 不同 */
  sprintf(buf, "%ld_%ld", now, rand());
  sprintf(gu.uid, "s:%d:\"%s\"", strlen(buf), buf);

  umask(0002);

  if (!create_file(gu, buf))
  {
    gallery_log("ERROR CREATING USER PROFILE");
    vmsg("錯誤:無法建立資料檔,請通知站長!");
  }
  else if (!create_album(gu, buf))
  {
    gallery_log("ERROR CREATING DIRECTORY");
    vmsg("錯誤:無法建立相簿,請通知站長!");
  }
  else
  {
    gallery_log("CREATE ALBUM");
    vmsg("已建立資料 :)");
  }

  return XEASY;
}



程式說明:

* 先裝 gallery 吧,FreeBSD 可以用 ports : /usr/ports/www/gallery
  不然就去 http://gallery.sf.net 抓。

* FreeBSD 已經預設裝 md5 了,如果其他系統沒有裝 MD5 的話,請自行安裝。

* 去抓 ftp://php.twbbs.org/pub/bbs/gallery/etc 裡面的東西,放到 BBS 家目錄
  下的 etc/gallery 裡面。這是 album.dat 的內容,直接拿來用然後換上自訂的欄
  位,gallery 會很聰明的把該資料夾當作是相簿。

  當然這邊可以作很多變化,在 album.dat.head 的最後幾個欄位有一個是

    s:15:"parentAlbumName";i:0;

  指的是該目錄的父目錄為何,如果想把 bbs 使用者申請的目錄都放到某個
  資料夾下面的話 (比如 bbs),先用 gallery 建立 bbs 相簿,然後修改
  album.dat.head,把上面那些字串改為

    s:15:"parentAlbumName";s:3:"bbs";

  "bbs" 前面的 3 就是指 "bbs" 這個字串的長度,依此類推可以換成
  你想要的資料夾名稱。

* 要把這二個目錄的權限
  /home/data/www/albums
  /home/data/www/albums/.users
  讓 bbs 身分可以寫入。

* 這樣子應該就行了 :D

  如果有問題歡迎提出 :)

  程式目前不確定是否為 bug free,如果因為使用這支程式造成 CPU 燒掉,
  資料消失,記憶體不見,被人入侵,女朋友跑掉或是股市套牢,本人不負責。 :pp

--
                                                      我的簽名檔只有十個字.
--
   ^..^    < 豬 頭 紀 公 園 - php.twbbs.org (140.113.208.200) >
 -w @@ w--                          < bittern.csie.nctu.edu.tw >
精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻