2011-01-09

FUSE - хэрэглэгчийн орон зайн файл систем

Сүүлийн үед үүл, тархай систем гэсэн нэр томьёонуудыг олонтаа сонсох боллоо. Сүлжээ ашиглан зарим файлуудыг өөр тооцоолуур дээр хадгалаж, өөрийн тооцоолуур дээр байгаа мэтээр хандах гэх мэт олон дэвшилтэт арга замууд бие болсон ба ийм технологи дээр суурилсан олон start-up компани бий болсон.

Энэ бичлэгтээ ийм технологи хийхэд маш их тус болдог FUSE (хэрэглэгчийн орон зайн файл систем) дээр жишээ хийж үзсэнээ хуваалцья гэж бодлоо. Юниксжуу үйлдлийн систем дээр байгаа файл системийг хүссэнээрээ харж хэрэглэхэд тус болдог цөмийн модуль юм.

За тэгэхээр нэг ийм жишээ бичье. Та өөрийгөө тагнуулч байна гэж бод. Тагнаж байгаа хүнийхээ гэрт орлоо. Хэрэглэгчийн тодорхой хугацаанд хандсан файлыг эсвэл хамгийн сүүлд хандсан файлыг олохыг хүслээ гэж бодьё. Энэ жишээн дээр бичих програм маань тодорхой хавтасыг хувьсагч болгож өгөөд ажиллуулахад тэр хавтасан дотор байгаа файлуудыг хамгийн сүүлд өөрчлөгдсөн жил, сар, өдөр, цагаар нь ангилладаг програм байх юм.

Жишээ нь, доорх шиг хавтасыг ангилья гэж бодьё:

Дээрх зурган дээр файлын нэрүүдийн өмнөх багана файлын хамгийн сүүлд өөрчлөгдсөн огноо болохыг анхаарна уу!

Тэгвэл програмыг ажиллуулсаны хүчинд доорх байдлаар харж болох юм.

Дээрх зурган дээр бид ангилсан хавтасуудын тусламжтайгаар 2010 оны 05 сарын 10-нь 01 цагт хамгийн сүүлд өөрчлөгдсөн файлыг харж байгаа юм.

За ингээд жишээний мааны код:

modiffs.c


#define FUSE_USE_VERSION 26

static const char * modiffsVersion = "2010.12.24";

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/xattr.h>
#include <dirent.h>
#include <unistd.h>
#include <fuse.h>
#include <time.h>

#define STACK_SIZE 250

typedef struct stack_s {
   char * items[STACK_SIZE];
   int size;
} stack;

int stack_exist(stack * s, char * elem) {
   int i = 0;
   for (i=0; i < s->size; i++) {
       if (strcmp(elem, s->items[i]) == 0) {
           return 1;
       }
   }
   return 0;
}

void stack_push(stack * s, char * elem) {
   s->items[s->size++] = elem;
}

int dir_depth(const char * path) {
   int depth = 0;
   char * temp = strchr(path, '/');
   while (temp != NULL) {
       depth++;
       temp = strchr(temp + 1, '/');
   }
   return depth;
}

char * full_path(char * upath, char * d_name) {
   char * ret = (char *) malloc(sizeof(char)*(strlen(upath) + strlen(d_name) + 1));
   strcpy(ret, upath);
   strcat(ret, d_name);
   return ret;
}

// Global to store our read-write path
char * rw_path;

// Translate an modiffs path into it's underlying filesystem path
static char * translate_path(const char * path) {

   char * rPath= malloc(sizeof(char)*(strlen(path)+strlen(rw_path)+1));

   strcpy(rPath, rw_path);
   if (rPath[strlen(rPath)-1]=='/') {
       rPath[strlen(rPath)-1]='\0';
   }
  
   int depth = dir_depth(path);
  
   if (strcmp("/", path) == 0) {
       strcat(rPath, "/");
   } else if (depth < 5) {
       strcat(rPath, "/");
   } else {
       int i = 0;
       char * temp = strchr(path, '/');
       while (i < (depth-1)) {
           i++;
           temp = strchr(temp + 1, '/');
       }
       strcat(rPath, "/");
       strcat(rPath, temp);
   }
  
   return rPath;
}

/*
* level:
* 0: year
* 1: month
* 2: day
* 3: hour
*/
char * last_attr(const char * path, int level) {   
   int depth = 0;
   char * cont = (char *) malloc(sizeof(char)*strlen(path));
   strcpy(cont, path);
   char * temp = strtok(cont, "/");
   while (depth < level && temp != NULL) {
       depth++;
       temp = strtok(NULL, "/");
   }
   return temp;
}

/******************************
*
* Callbacks for FUSE
*
******************************/

static int modiffs_getattr(const char * path, struct stat * stbuf) {
  
   int res = 0;
   int depth = dir_depth(path);
   memset(stbuf, 0, sizeof(struct stat));
  
   if (strcmp(path, "/") == 0) {
       stbuf->st_mode = S_IFDIR | 0755;
       stbuf->st_nlink = 1;
       stbuf->st_ctime = time(NULL);
       stbuf->st_atime = time(NULL);
       stbuf->st_mtime = time(NULL);
       stbuf->st_size = 4096;
   } else if (depth < 5) {       
       stbuf->st_mode = S_IFDIR | 0444;
       stbuf->st_nlink = 1;
       stbuf->st_ctime = time(NULL);
       stbuf->st_atime = time(NULL);
       stbuf->st_mtime = time(NULL);
       stbuf->st_size = 4096;
   } else {       
       char * upath = translate_path(path);
       res = lstat(upath, stbuf);
       free(upath);
       if(res == -1) {
           return -errno;
       }
   }

   return res;
}

static int modiffs_readlink(const char *path, char *buf, size_t size)
{
   int res;
   char * upath = translate_path(path);

   res = readlink(upath, buf, size - 1);
   free(upath);
   if(res == -1) {
       return -errno;
   }
   buf[res] = '\0';
   return 0;
}

static int modiffs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) {
  
   DIR * dp;
   struct dirent * de;
   int res;
  
   struct tm *ts;
  
   (void) offset;
   (void) fi;
  
   int depth;
  
   char * upath = translate_path(path);
  
   dp = opendir(upath);
  
   if(dp == NULL) {
       res = -errno;
       return res;
   }
  
   filler(buf, ".", NULL, 0);
   filler(buf, "..", NULL, 0);
  
   if (strcmp("/", path) == 0) {       
       stack years;
       years.size = 0;
       while((de = readdir(dp)) != NULL) {       
           struct stat st_modif;
           memset(&st_modif, 0, sizeof(st_modif));
           char * year = (char *) malloc(sizeof(char) * 5);           
           stat(full_path(upath, de->d_name), &st_modif);
           ts = localtime(&(st_modif.st_mtime));
           strftime(year, 255, "%Y", ts);
           if (stack_exist(&years, year) == 0) {
               stack_push(&years, year);
               filler(buf, year, NULL, 0);
           }
       }
   } else {
       depth = dir_depth(path);
       if (depth == 1) {
           stack months;
           months.size = 0;
           while((de = readdir(dp)) != NULL) {       
               struct stat st_modif;
               memset(&st_modif, 0, sizeof(st_modif));
               char * year = (char *) malloc(sizeof(char)*5);
               char * month = (char *) malloc(sizeof(char)*3);
               stat(full_path(upath, de->d_name), &st_modif);
               ts = localtime(&(st_modif.st_mtime));
               strftime(year, 255, "%Y", ts);
               strftime(month, 255, "%m", ts);
               if (strcmp(last_attr(path,0), year) == 0) {
                   if (stack_exist(&months, month) == 0) {
                       filler(buf, month, NULL, 0);
                       stack_push(&months, month);
                   }
               }
           }
       } else if (depth == 2) {
           stack days;
           days.size = 0;
           while((de = readdir(dp)) != NULL) {       
               struct stat st_modif;
               memset(&st_modif, 0, sizeof(st_modif));
               char * year = (char *) malloc(sizeof(char)*5);
               char * month = (char *) malloc(sizeof(char)*3);
               char * day = (char *) malloc(sizeof(char)*3);
               stat(full_path(upath, de->d_name), &st_modif);
               ts = localtime(&(st_modif.st_mtime));
               strftime(year, 255, "%Y", ts);
               strftime(month, 255, "%m", ts);
               strftime(day, 255, "%d", ts);
              
               if (strcmp(last_attr(path,0), year) == 0 &&
                   strcmp(last_attr(path,1), month) == 0) {
                   if (stack_exist(&days, day) == 0) {
                       stack_push(&days, day);
                       filler(buf, day, NULL, 0);
                   }
               }                           
           }
       } else if (depth == 3) {
           stack hours;
           hours.size = 0;
           while((de = readdir(dp)) != NULL) {       
               struct stat st_modif;
               memset(&st_modif, 0, sizeof(st_modif));
               char * year = (char *) malloc(sizeof(char)*5);
               char * month = (char *) malloc(sizeof(char)*3);
               char * day = (char *) malloc(sizeof(char)*3);
               char * hour = (char *) malloc(sizeof(char)*3);
               stat(full_path(upath, de->d_name), &st_modif);
               ts = localtime(&(st_modif.st_mtime));
               strftime(year, 255, "%Y", ts);
               strftime(month, 255, "%m", ts);
               strftime(day, 255, "%d", ts);
               strftime(hour, 255, "%H", ts);
              
               if (strcmp(last_attr(path,0), year) == 0 &&
                   strcmp(last_attr(path,1), month) == 0 &&
                   strcmp(last_attr(path,2), day) == 0) {
                   if (stack_exist(&hours, hour) == 0) {
                       stack_push(&hours, hour);
                       filler(buf, hour, NULL, 0);
                   }
               }                           
           }
       } else {
           while((de = readdir(dp)) != NULL) {
               if (strcmp(".", de->d_name) == 0 || strcmp("..", de->d_name) == 0) {
                   continue;
               }             
              
               struct stat st_modif;
               memset(&st_modif, 0, sizeof(st_modif));
               char * year = (char *) malloc(sizeof(char)*5);
               char * month = (char *) malloc(sizeof(char)*3);
               char * day = (char *) malloc(sizeof(char)*3);
               char * hour = (char *) malloc(sizeof(char)*3);
               stat(full_path(upath, de->d_name), &st_modif);
               ts = localtime(&(st_modif.st_mtime));
               strftime(year, 255, "%Y", ts);
               strftime(month, 255, "%m", ts);
               strftime(day, 255, "%d", ts);
               strftime(hour, 255, "%H", ts);
              
               if (strcmp(last_attr(path,0), year) == 0 &&
                   strcmp(last_attr(path,1), month) == 0 &&
                   strcmp(last_attr(path,2), day) == 0 &&
                   strcmp(last_attr(path,3), hour) == 0) {
                  
                   struct stat st;
                   memset(&st, 0, sizeof(st));
                   st.st_ino = de->d_ino;
                   st.st_mode = de->d_type << 12;

                   if (filler(buf, de->d_name, &st, 0)) {
                       break;
                   }
               }
           }
       }
   }
  
   free(upath);
   closedir(dp);
  
   return 0;
}

static int modiffs_mknod(const char *path, mode_t mode, dev_t rdev)
{
   (void)path;
   (void)mode;
   (void)rdev;
   return -EROFS;
}

static int modiffs_mkdir(const char *path, mode_t mode)
{
   (void)path;
   (void)mode;
   return -EROFS;
}

static int modiffs_unlink(const char *path)
{
   (void)path;
   return -EROFS;
}

static int modiffs_rmdir(const char *path)
{
   (void)path;
   return -EROFS;
}

static int modiffs_symlink(const char *from, const char *to)
{
   (void)from;
   (void)to;
   return -EROFS;
}

static int modiffs_rename(const char *from, const char *to)
{
   (void)from;
   (void)to;
   return -EROFS;
}

static int modiffs_link(const char *from, const char *to)
{
   (void)from;
   (void)to;
   return -EROFS;
}

static int modiffs_chmod(const char *path, mode_t mode)
{
   (void)path;
   (void)mode;
   return -EROFS;

}

static int modiffs_chown(const char *path, uid_t uid, gid_t gid)
{
   (void)path;
   (void)uid;
   (void)gid;
   return -EROFS;
}

static int modiffs_truncate(const char *path, off_t size)
{
   (void)path;
   (void)size;
   return -EROFS;
}

static int modiffs_utime(const char *path, struct utimbuf *buf)
{
   (void)path;
   (void)buf;
   return -EROFS;
}

static int modiffs_open(const char *path, struct fuse_file_info *finfo)
{
   int res;
  
   int flags = finfo->flags;

   if ((flags & O_WRONLY) || (flags & O_RDWR) || (flags & O_CREAT) || (flags & O_EXCL) || (flags & O_TRUNC) || (flags & O_APPEND)) {
       return -EROFS;
   }
  
   char * upath = translate_path(path);

   res = open(upath, flags);

   free(upath);
   if(res == -1) {
       return -errno;
   }
   close(res);
  
   return 0;
}

static int modiffs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *finfo)
{
   int fd;
   int res;
   (void)finfo;

   char * upath = translate_path(path);
   fd = open(upath, O_RDONLY);
   free(upath);
   if(fd == -1) {
       res = -errno;
       return res;
   }
   res = pread(fd, buf, size, offset);

   if(res == -1) {
       res = -errno;
   }
   close(fd);
   return 0;
  
}

static int modiffs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *finfo)
{
   (void)path;
   (void)buf;
   (void)size;
   (void)offset;
   (void)finfo;
   return -EROFS;
}

static int modiffs_statfs(const char *path, struct statvfs *st_buf)
{
   int res;
   char * upath = translate_path(path);
   res = statvfs(upath, st_buf);
   free(upath);
   if (res == -1) {
       return -errno;
   }
   return 0;
}

static int modiffs_release(const char *path, struct fuse_file_info *finfo)
{
   (void) path;
   (void) finfo;
   return 0;
}

static int modiffs_fsync(const char *path, int crap, struct fuse_file_info *finfo)
{
   (void) path;
   (void) crap;
   (void) finfo;
   return 0;
}

static int modiffs_access(const char *path, int mode)
{
   int res;
   char *upath = translate_path(path);

   /* Don't pretend that we allow writing
    * Chris AtLee <chris@atlee.ca>
    */
   if (mode & W_OK)
       return -EROFS;

   res = access(upath, mode);
   free(upath);
   if (res == -1) {
       return -errno;
   }
   return res;
}

struct fuse_operations modiffs_oper = {
   .getattr     = modiffs_getattr,
   .readlink    = modiffs_readlink,
   .readdir     = modiffs_readdir,
   .mknod       = modiffs_mknod,
   .mkdir       = modiffs_mkdir,
   .symlink     = modiffs_symlink,
   .unlink      = modiffs_unlink,
   .rmdir       = modiffs_rmdir,
   .rename      = modiffs_rename,
   .link        = modiffs_link,
   .chmod       = modiffs_chmod,
   .chown       = modiffs_chown,
   .truncate    = modiffs_truncate,
   .utime       = modiffs_utime,
   .open        = modiffs_open,
   .read        = modiffs_read,
   .write       = modiffs_write,
   .statfs      = modiffs_statfs,
   .release     = modiffs_release,
   .fsync       = modiffs_fsync,
   .access      = modiffs_access
};
enum {
   KEY_HELP,
   KEY_VERSION,
};

static void usage(const char* progname)
{
   fprintf(stdout,
           "usage: %s readwritepath mountpoint [options]\n"
           "\n"
           "   Mounts readwritepath as a read-only mount at mountpoint\n"
           "\n"
           "general options:\n"
           "   -o opt,[opt...]     mount options\n"
           "   -h  --help          print help\n"
           "   -V  --version       print version\n"
           "\n", progname);
}

static int modiffs_parse_opt(void *data, const char *arg, int key,
                         struct fuse_args *outargs)
{
   (void) data;

   switch (key)
   {
   case FUSE_OPT_KEY_NONOPT:
       if (rw_path == 0)
       {
           rw_path = strdup(arg);
           return 0;
       }
       else
       {
           return 1;
       }
   case FUSE_OPT_KEY_OPT:
       return 1;
   case KEY_HELP:
       usage(outargs->argv[0]);
       exit(0);
   case KEY_VERSION:
       fprintf(stdout, "ROFS version %s\n", modiffsVersion);
       exit(0);
   default:
       fprintf(stderr, "see `%s -h' for usage\n", outargs->argv[0]);
       exit(1);
   }
   return 1;
}

static struct fuse_opt modiffs_opts[] = {
   FUSE_OPT_KEY("-h",          KEY_HELP),
   FUSE_OPT_KEY("--help",      KEY_HELP),
   FUSE_OPT_KEY("-V",          KEY_VERSION),
   FUSE_OPT_KEY("--version",   KEY_VERSION),
   FUSE_OPT_END
};

int main(int argc, char *argv[])
{
   struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
   int res;

   res = fuse_opt_parse(&args, &rw_path, modiffs_opts, modiffs_parse_opt);
   if (res != 0)
   {
       fprintf(stderr, "Invalid arguments\n");
       fprintf(stderr, "see `%s -h' for usage\n", argv[0]);
       exit(1);
   }
   if (rw_path == 0)
   {
       fprintf(stderr, "Missing readwritepath\n");
       fprintf(stderr, "see `%s -h' for usage\n", argv[0]);
       exit(1);
   }

   fuse_main(args.argc, args.argv, &modiffs_oper, NULL);

   return 0;
}

Дээрх кодыг Убунту дээр ирдэг fuse-rofs багцын эх код дээр өөрчлөлт хийж бий болгосоныг анхаарна уу!

Эмхэтгэж ажиллуулахын тулд:

test.sh

gcc -o modiffs -Wall -ansi -W -std=c99 -g -ggdb -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -lfuse modiffs.c fusermount -u /home/dagvadorj/Desktop/u sudo umount /home/dagvadorj/Desktop/u ./modiffs /home/dagvadorj/Desktop/untitled /home/dagvadorj/Desktop/u

2010-11-12

Монгол хүний хийсэн програмын хэл

Яаая, хүний анхаарал татах гээд лаг гарчиг тавьцан.

2 сарын өмнөөс нэг хэлмэрчилдэг програмын хэл хийж эхэлсэн юмаа. Одоо альфа хувилбараа толилуулмаар байна. Дуусах яагаачгүй байгаа болохоор "0.81" хувилбар гэж нэрлэе.

Энэ хаягаас татаж авч болно. http://www.box.net/shared/sqp3d08p9e

Татаж авсны дараа задлаад root хэрэглэгчээр орсны дараа доорх коммандуудыг ажиллуулна.

# make
# litelang example.lite
example.lite болон түүн дотроос дуудагдаж байгаа factorial.lite програм нь доорх агуулгатай.

example.lite

print("Тавтай морил!")

include("factorial.lite")

a=7
b=4
print("a=",a,", b=",b)
print("a+b=", a+b)
print("a/b=", a/b)
print("a%b=", a%b)
print("a!=",factorial(a))
print(8,"!=",factorial(8))

gcd = func(x,y)
  while y > 0
    z = y
    y = x%y
    x = z
  end
  return(x)
end

print("15,12 хоёр тооны хамгийн их ерөнхий хуваагч бол: ",gcd(15,12))

print("Таны нэр: ")
a = input()
print("Сайн уу, ", a)

print("
litelang програмын хэл нь одоогийн байдлаар
альфа шатандаа байна.
")

factorial.lite

print("
Энэ файлд факториал функцийн тодорхойлолт бий.
")

factorial = func(n)
    value = 1
    while n>0
       value *= n
       n -= 1
    end
    return(value)
end

2010-10-01

General purpose linked list, stack and queue for C

Programmers refer to use modern programming languages like Java, Python or Ruby for their uses, because of their powerful built-in functions and flexibility. However, sooner or later, a programmer will have to face their old fella C someday.

For me, I had to use C when I decided to write an interpreter for a programming language I am developing. Of course, C lack of a bunch of stuff, which other modern languages have like hash table, and indexing of a list with a negative index (Python can do list[-2]), etc. But the first things I needed were stack, queue and linked list. We always write these ourselves when programming in C.

Here, I wrote a code for a linked list which can be used as stack and queue and supports negative indexing. Followings are the codes hosted on Google Code:

http://code.google.com/p/litelang/source/browse/trunk/litelang/slist.h (Includes description for methods)

http://code.google.com/p/litelang/source/browse/trunk/litelang/slist.c

Peace!

2010-05-12

Image Processing буюу Зураг Боловсруулалт

Номын санд явж байсан манай сургуулийн нэг Камбуж залуу нэг даалгавар хараадхаа гэхээр нь очоод харсан сонирхолтой санагдаад хийж үзлээ.

ppm төрлийн зургийн файл нь ASCII форматаар илэрхийлэгддэг юм байна.

Жишээ нь доорх шиг ppm форматтай зургийг текст эдитор дээр нээвэл хажуудахь шиг харагдана.

Файлыг эндээс татаж авч болно.

ASCII кодыг тайлбарлавал:
P3 # форматын төрөл
150 150 # зургийн өргөн, урт
255 # хэрэглэгдсэн максимум өнгө
176 # эхний цэгийн RGB кодын Red
158 # эхний цэгийн RGB кодын Green
158 # эхний цэгийн RGB кодын Blue
172 # хоёр дахь цэгийн RGB кодын Red
152 # хоёр дахь цэгийн RGB кодын Green
153 # хоёр дахь цэгийн RGB кодын Blue

3 дахь мөрөөс хойш 150x150x3 мөр байна. Учир нь 3 тоо нэг цэгийн өнгийг илэрхийлж байна.

Тэгээд код бичиж үзлээ, энгийн мөртлөө их таалагдлаа. Програмыг ажиллуулахад доорх дөрвөн зураг ppm форматаар үүсэх юм.

Хүний арьсны өнгийг аватарын арьсны өнгөтэй төстэй болгодог болохоор ингэж нэрлэлээ :) Зургийн RGB кодны улаан, цэнхэр хоёр утгыг нь солиход гарна Зургийн нэгатив Зургийн хэмжээг 2 дахин багасгасан байдал Толинд харсан байдал

За ингээд эцэст нь кодоо хавсаргая:


#include 

#include 



int main() {

        FILE * input;
        FILE * avatar;

        FILE * negative;

        FILE * small;
        FILE * mirror;

        int i, m;

        int width, height, max;

        char fname[20];
        

        printf("Enter the name of the file: ");

        scanf("%20s", &fname);
        

        input = fopen(fname, "r");
        avatar = fopen("avatar.ppm", "w");

        negative = fopen("negative.ppm", "w");

        small = fopen("small.ppm", "w");
        mirror = fopen("mirror.ppm", "w");

        
        if (input == NULL) {

           printf("ERROR: The file can not be found!\n");

           return -1;

        }
        

        fscanf(input, "P3\n%d %d\n%d", &width, &height, &max);
        fprintf(avatar, "P3\n%d %d\n%d\n", width, height, max);

        fprintf(negative, "P3\n%d %d\n%d\n", width, height, max);

        fprintf(small, "P3\n%d %d\n%d\n", width/2, height/2, max);
        fprintf(mirror, "P3\n%d %d\n%d\n", width, height, max);

        
        int dim = width*height;

        int temp[dim][3];

        
        for (i=0;i < dim;i++) {

            fscanf(input, "%d %d %d ", &temp[i][0], &temp[i][1], &temp[i][2]);

            fprintf(avatar, "%d %d %d ", 

                temp[i][2], 

                temp[i][1], 

                temp[i][0]);
            fprintf(negative, "%d %d %d ", 

                max-temp[i][0], 

                max-temp[i][1], 

                max-temp[i][2]);

            if ((i/width)%2==0) {

                if (i%2==0)

                   fprintf(small, "%d %d %d ", 

                       temp[i][0], 

                       temp[i][1], 

                       temp[i][2]);

            }

        }
    
        for (i=0;i < dim;i++) {
        m = (i/width)*width+width-i%width-1;
        fprintf(mirror, "%d %d %d ", temp[m][0], temp[m][1], temp[m][2]);
        }
        

        fclose(input);
        fclose(avatar);

        fclose(negative);

        fclose(small);
        fclose(mirror);

        return 0;

}

Дажгүй цэгцтэй код боллоо. Зураг том бол RAM-д их зай эзлэх нь дээ. :(

2010-05-08

Confession of an Invader

Nearly 1.5 thousand light years from home and we finally made it. 2060 AD, a united space expedition called Confederation of Space Missions discovered a new planet with life on it. After leaving the Earth which has ultimately limited resource and overpopulation, the team finally made to one of 50 moons of NZ53-04 planet in the NZ-53 solar system, which was first located in the 2010s. This moon, relatively younger than our Earth, has enormous amount of aqua and a very dynamic life-form.

This was supposed to be the home, new hope for the mankind. About 2.3 times bigger than the Earth, physically the planet is formed by highlands and deep valleys. The planet has magnificent amount of dissipate, the planet is almost all covered with deep cloud, the highlands are similar to shallow rain forests and streams on it are fed by the clouds. What are in the deep valleys and what is happening out there is mystery. Earlier expeditions reported deathly fauna – giant lizard-like creatures and scary jungle. People called these deep valleys “death” valleys.

We called the planet Renzhou, Chinese for “Man's dominion”, though its indigenous intellectual creatures are the Mangi. Mangis, koala-sized creatures, have tribal societies like earlier plains people. They lived in the planet's highlands. Although, they seemed frightened when the research teams first came, they became friendly shortly.

The cloud making an layer underneath the planet's atmosphere made people hard to breathe, since the pressure was too high. It was a major obstacle for forming colonies alongside the planet since everyone with wear special costume and people would only live in facilities. It was impossible because the first immigration package from the Earth would include some 4 billion people and livestock. Scientists came out with a solution. The solution was to use microwave and chemicals to reduce the amount of the cloud. They were successful. The cloud did became less.

Understanding that the planet's weather condition was changing as a result of humans actions, the mangis were unpleasant with the situation. Clashes of different sizes took place in the highlands. Approved by the United Nations, army regiments and raged volunteers started war against the mangis. As a result the mangis were relocated to the death valleys.

We established colonies on the highlands. New Australland, Ningpo, Nova Occitan, Fukian, Formosa, and Gulliver were among the first ones. Minor mutations were observed among people. This phenomenon first was thought to be fine. It was later proved that the thick cloudy structure covering the planet was making the life on Renzhou immune to the toxic substances coming from NZ-53 and NZ-53-04.

The cloud was unrecoverable since the forests both in the highlands and the deep valleys are decreased 80% in size and the water supply has decreased 65%. 44 years ago, man was first coming to Renzhou, and today we are leaving the planet with our spaceships. I am one of the few people who were lucky enough to be on one of the ships. About 3.4 billion people are left on the planet for definite death. We, on the ships, are all infected with the toxins. It is most probably that we all be died as well.

Evolution, “the stronger beats the weaker”, cruelty, Darwin's law, war, violence, … Unfortunately, it seems that they will always exist alongside with human.

2010-05-01

Downloading your e-mail on a server to process

You know all the great features of craigslist and Facebook, that use anonymous, standalone e-mail for forwarding request to an ad owner or replying to a message via e-mail.

Well, I will show you how to do something like these.

Scenario: An chronological script will download new e-mails, then a Python script will process on these e-mails.

For downloading e-mails, I used getmail4. The best tutorial for it can be found here.

For my case, /home/manchurian/.getmail/getmailrc looks like this:

[retriever]
type = SimplePOP3Retriever
server = [my_mail_server]
username = [my_mail]
password = [my_mail_password]

[destination]
type = Mboxrd
path = /home/manchurian/inbox

Make the mail downloading automatic using crontab -e:

* * * * * getmail -n
-n is for retrieving new mails only.

Now it is time to process the downloaded mails anyway you want:

import mailbox
mails = mailbox.mbox("/home/manchurian/inbox")

mails.lock()

try:
   for m in mailbox:
      if m['from'] == 'abc@abc.org':
         print m['subject']
finally:
   mails.unlock()

Cheers,

Backing up MySQL database

Losing data on your business application's database would be a real disaster. Here's a way simple script to back up your MySQL database.

Scenario

We have a remote Debian server with the database, and an Ubuntu server (Intel Xeon) in our office right beneath my table. :)

We wanted to have our database backed up daily. So here we go:

1-st step. Save SQL script of the database in the remote server.


#!/bin/bash
export d=$(date +'%Y-%m-%d')
mkdir -p /root/backup/$d
mysqldump --add-drop-table --allow-keywords -q -a -c -u root -p[password_for_mysql_root] [databasename] > /root/backup/$d/[databasename].sql

Save it as /root/mysqlbackup.sh

2-nd step. Automize it with crontab -e to run daily at 05:30.

30 05 * * * /root/mysqlbackup.sh

3-rd step. Fetch the SQL from the local server and save.

#!/bin/bash
export d=$(date +'%Y-%m-%d')
mkdir -p /root/backup/$d
pscp -sftp -l root -pw [password_for_remote_server_root] root@[server_ip]:/root/backup/$d/[databasename].sql /root/backup/$d
exit 0