פלאנט תוכנה חופשית בישראל (Planet FOSS-IL)

01 מרץ, 2015

Boris Shtrasman

ענני


השבוע חזרתי קצת לילדות בשביל להרים סביבת עבודה נוחה יותר לבית; מפה לשם הייתי צריך להיזכר באיך מרימים שרתי דוא"ל ,שירותי קבצים (webdav) ואימות.תוך כדי הבנייה קיבלתי תזכורת כואבת כי צריך לתרגל  כי אחרת שוכחים דברים מה שהוביל לכמעט יום עבודה במקום מספר שעות בודדות.

המערכת בנוייה בצורה הבאה :

כל לקוח שצריך להתחבר למערכת מתחבר באמצעות openvpn לתוך הרשת הפנימית שלי ושם מקבל שירותי דוא"ל , אנשי קשר,ויומן.



שירותי ה DNS שבתוך שרת ה openvpn ניתנים ע"י bind9, שירותי הדואל מסופקים ע"י dovecot ו exim4 היומן ואנשי הקשר מסופקים ע"י ownloud.

בשביל ה SSL יצרתי לעצמי CA אישי וחתמתי על האישורים ע"י ה CA הזה , לאחר מכן התקנתי את האישור בכל אחד מהמכשירים שצריכים להתחבר (הנה מדריך מצויין).

שירותי ההזדהות של exim משתמשים ב SASL (בחרתי ב SASL כי אני רוצה לחבר גם ejabbered לסביבה וזה יקל עלי את החיים לאחר מכאן) (מדריך כאן).

בגלל שבחרתי לעבוד עם משתמשים אמיתיים (ולא וירטואליים) נכון לרגע זה , הדבר מאפשר שכל משתמש מכיל את האפשרות לקבל את כל המיילים שלו מגימייל לשירות המייל הפנימי ע"י הגדרה אישית מולו.

פעולה זו מתבצעת ע"י fetchmail + cron , יש ליצור הגדרה עבור כל משתמש שרוצה את העבודה בצורה הבאה :

usera@sinta:~$ cat .fetchmailrc

poll pop.gmail.com with proto POP3 and options no dns port 995 user gmailuser@gmail.com there with password gmailpassword is usera here options ssl


לאחר מכאן ביצוע crontab -e מתוך המשתמש בשביל להוסיף את fetchmail -vk.

לאחר מכן לקוח אנדרויד יכול למשוך את ההודעות ע"י שימוש ב K9 ולגשת לממשק המשתמש ע"י הדפדפן האוהב עליו.

להפתעתי גיליתי של firefox 35 שמסופק ע"י f-droid יש בעייה בעבודה עם שירות ה dns שנדחף ע"י openvpn בגלל באג פתוח עד 35 כולל, בגירסה 36 זה קורה פחות אבל זה היה פשוט מטמטם הבטיחו לתקן ב 37 נחייה ונראה.

עבור המערכת שתספק אנשי הקשר והיומן בחרתי ב owncloud במקום ב kolab או citadel ללא שום סיבה מיוחדת.בדרך גיליתי עד כמה ממשק המשתמש של owncloud איטי ועקום לטעמי, אבל שאר המערכות נראות כמתפקדות ללא שום בעייה ייתכן וזה קשור לעובדה שכל זה רץ מתוך רסבריי פי.

לדוגמה ייבוא יומנים מ ICS  - הדרך לייבא היא העלאה של הקובץ ולאחר מכאן (דרך ממשק משתמש) ללחוץ עליו ורק אז תשאל לאן תרצה לייבא את היומן.

עיגון תיקיות ה webdav ככונן משותף עבד חלק בדביאן, בוינדוס 7 ובאנדרואיד השתמשתי באפליקציה (הצולעת לטעמי) owncloud.

השלב הבא בבנייה (שאותה לא עשיתי עדיין) הוא הרמה של slapd וכיוון של כלל המערכות לעבוד מולו, אני חושב שזה עדיף בשביל הזיהוי מאשר עבודה מול טבלאות בשרת דואל (כך גם אין לי vendor lock מעצבן כמו שיש ב KDE). בניית סביבת ejabbered ועוד.

01 מרץ, 2015 06:35 PM

תודה לשלומי

הייתי צריך לנקות קצת את הראש היום בגלל באג שאני עובד עליו, ואז וראיתי הודעה על פרוייקט אויילר ב פלאנט.

מי שלא מכיר את פרוייקט אויילר , זה אחד המקומות היותר טובים שאני מכיר לנסות דברים תוך כדי לימוד.

ההצעה שלי לפתרון השאלה איך לעשות אופטימיזציה לחישוב מספר ראשוני היא שימוש ב composition (אבל זה בא על חשבון הקצעה) :

 
#include <stdio.h>
#include <time .h>
#include <string.h>

#define mMO_NUM_LIMIT (150000000)

static char mo_tabOfPrimes[mMO_NUM_LIMIT];

void mark_numbers_as_primes()
{
int primeIndex;
int compositionIndex;
int maxNumberOfElemenentsInTab;
memset(mo_tabOfPrimes,0,sizeof(mo_tabOfPrimes));
maxNumberOfElemenentsInTab = sizeof(mo_tabOfPrimes)/sizeof(mo_tabOfPrimes[0]);

for (primeIndex = 2 ;primeIndex < maxNumberOfElemenentsInTab;primeIndex ++ )
{
if (0 != mo_tabOfPrimes[primeIndex])
{
continue; //any number previously markes as a composition can no be prime
}
//any next value will be a composition of that code
for (compositionIndex = primeIndex + primeIndex; compositionIndex < maxNumberOfElemenentsInTab;compositionIndex = compositionIndex + primeIndex)
{
mo_tabOfPrimes[compositionIndex] = 1;
}
}
}

int is_prime(const long indexToCheck)
{
int check ;
if (indexToCheck > mMO_NUM_LIMIT)
{
return 0;
}
return (0 == mo_tabOfPrimes[indexToCheck]);
}

void printFirstNPrimes(int countToPrint)
{
long i;
int numberOfPrimesPrintedSoFar = 0;

for (i = 0 ;
( i < mMO_NUM_LIMIT) &&( numberOfPrimesPrintedSoFar < countToPrint);
i++)
{
if (1 == is_prime(i))
{
numberOfPrimesPrintedSoFar ++;
printf("%d/%d %d is a prime number\n",numberOfPrimesPrintedSoFar,countToPrint,i);
}
}
}
int main()
{
clock_t start;
clock_t end;
double time_spent;

start = clock();
mark_numbers_as_primes();
end = clock();
time_spent = (end - start) / CLOCKS_PER_SEC;
printf("spent %lf seconds when filling %lld prime numbers\n",time_spent,mMO_NUM_LIMIT);
printFirstNPrimes(100);
return 0;
}

01 מרץ, 2015 04:00 PM

צרות עם openvpn כאשר יש מכשיר אנדרויד ללא רוט

אחד המכשירים שמתחבר לענני הוא מכשיר שלא עבר rooting מה שאומר כי אני נאלץ להשתמש בלקוח openvpn ללא יכולת tap.

אז ישבתי והגדרתי במשך כ 5 דקות שלמות שרת openvpn כמו בדר"כ רק ע"י החלפה לשימוש ב tun במקום tap וההגדרה הראשונית נראתה כך :


port 1194
proto tcp
dev tun
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/server.crt
crl-verify /etc/openvpn/easy-rsa/keys/crl.pem
dh /etc/openvpn/easy-rsa/keys/dh1024.pem

server 192.168.0.0 255.255.255.0
push "route 192.168.1.0 255.255.255.0"
push "dhcp-option DNS 192.168.0.1"

client-to-client
keepalive 10 120
comp-lzo
persist-key
persist-tun
status openvpn-status.log
verb 4
mute 20
script-security 2

צורת העבודה הזאת מאפשרת dhcp ע"ג tun ועובדת בדביאן ווינדוס, כאשר ניסיתי להשתמש בהגדרות צד לקוח קיבלתי הודעה קריפטית לגבי dresses are not in the same /30 subnet (topology net30 מה שלכעצמו מוזר כי הכתובת שצריכה אמורה לעבור דרך dhcp. כמה שחיפשתי לא הצלחתי למצוא פתרון פרט ללספק כתובת (מאותו המרחב באמצעות שימוש בcient-config-dir ושם הגדרה של כתובת קבועה עבורו).

port 1194
proto tcp
dev tun
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/server.crt
crl-verify /etc/openvpn/easy-rsa/keys/crl.pem
dh /etc/openvpn/easy-rsa/keys/dh1024.pem

server 192.168.0.0 255.255.255.0
push "route 192.168.1.0 255.255.255.0"
push "dhcp-option DNS 192.168.0.1"

client-config-dir ccd
route 192.168.0.0 255.255.255.252


client-to-client
keepalive 10 120
comp-lzo
persist-key
persist-tun
status openvpn-status.log
verb 4
mute 20
script-security 2

לאחר מכאן יש ליצור תיקיית ccd ובתוכה שם כמו שהשתמשת בעת ייצרת certificate עבור הלקוח.

01 מרץ, 2015 12:58 PM

28 פברואר, 2015

Shlomi Fish

Tech Tip: How to Configure Qt 5 Behaviour When Running on KDE4

Recently, I noticed that when running the VLC-2.2.0 prerelease, which is based on Qt 5 for its GUI, on my Mageia Linux 5 system on top of KDE 4, then in the playlist a single-click immediately played a file instead of selecting it, while reserving a double click for activation. After a long amount of research and thought, I figured out a way to configure Qt 5 on top of KDE.

To do so:

  1. Install lxqt-config and the “lxqt-qtplugin”.

  2. Add the line “export QT_QPA_PLATFORMTHEME=lxqt” somewhere before the desktop startup in your “.Xclients” or “.xinitrc” file (or in your “.bashrc”).

  3. Restart the X/KDE environment.

  4. Run “lxqt-config” to configure the appropriate behaviour.

This way one can use the Qt5 customisations of lxqt in KDE 4. Enjoy!

Licence

You can reuse this entry under the Creative Commons Attribution 3.0 Unported licence, or at your option any later version. See the instructions of how to comply with it.

28 פברואר, 2015 12:12 PM

26 פברואר, 2015

Shlomi Fish

“Out of the Strong, Something Sweet” - How a Bug Led to a Useful Optimisation

The book Fortune or Failure: Missed Opportunities and Chance Discoveries (which my family used to own, but which I did not read) gives the case to the important role of luck and chance in scientific discoveries. Recently, when working on Project Euler Problem No. 146 I came up with a case of an accidental bug, that in turn led to an idea for a significant optimisation.

The C code with the bug (which was in turn translated from some Perl code) looked something like that:

#define DIV 9699690
#define NUM_MODS 24024
#define NUM_PRIMES 8497392

int primes[NUM_PRIMES];
int mods[NUM_MODS];

typedef long long LL;

static inline bool is_prime(LL n)
{
    LL lim = (LL)(sqrt(n));

    for (int p_idx=0; p_idx < NUM_MODS ; p_idx++)
    {
        typeof (primes[p_idx]) p = primes[p_idx];
        if (p > lim)
        {
            return true;
        }
        if (n % p == 0)
        {
            return false;
        }
    }
    return true;
}

.
.
.
            for (int y_idx=0;y_idx<sizeof(y_off)/sizeof(y_off[0]);y_idx++)
            {
                if (! is_prime(sq + y_off[y_idx]))
                {
                    goto fail;
                }
            }
            for (int n_idx=0;n_idx<sizeof(n_off)/sizeof(n_off[0]);n_idx++)
            {
                if (is_prime(sq + n_off[n_idx]))
                {
                    goto fail;
                }
            }

As you can notice eventually, the problem was that in the p_idx loop, NUM_MODS should have been the larger NUM_PRIMES. This caused the test for primality to finish faster, but to sometimes return true instead of false. As a result, I noticed that some numbers were erroneously reported as suitable, but the program finished much faster.

I corrected it and reran the program which was now much slower, but this led me to think that maybe the lower limit to the count of primes can be a pre-filter for primality for the “y_idx”/“y_off” numbers, that will run quicker and eliminate some numbers. As a result, I did this:

#define NUM_PRIMES__PRE_FILTER 24024

static inline bool is_prime__pre_filter(LL n)
{
    LL lim = (LL)(sqrt(n));

    for (int p_idx=0; p_idx < NUM_PRIMES__PRE_FILTER ; p_idx++)
    {
        typeof (primes[p_idx]) p = primes[p_idx];
        if (p > lim)
        {
            return true;
        }
        if (n % p == 0)
        {
            return false;
        }
    }
    return true;
}

.
.
.
            for (int y_idx=0;y_idx<sizeof(y_off)/sizeof(y_off[0]);y_idx++)
            {
                if (! is_prime__pre_filter(sq + y_off[y_idx]))
                {
                    goto fail;
                }
            }
            for (int y_idx=0;y_idx<sizeof(y_off)/sizeof(y_off[0]);y_idx++)
            {
                if (! is_prime(sq + y_off[y_idx]))
                {
                    goto fail;
                }
            }
            for (int n_idx=0;n_idx<sizeof(n_off)/sizeof(n_off[0]);n_idx++)
            {
                if (is_prime(sq + n_off[n_idx]))
                {
                    goto fail;
                }
            }

This made the program finish in under a minute, while yielding the correct solution. The original program, with the bug fix, was still running after several minutes.

So the bug proved to be useful and insightful. One possible future direction is to merge the two “y_idx” loops into a single function that will accept an array of numbers, and will check them all for primality using the same divisors simultaneously, so as soon as one of them is found to be non-prime, a verdict will be reached.

Licence

You can reuse this entry under the Creative Commons Attribution Noncommercial 3.0 Unported licence, or at your option any later version. See the instructions of how to comply with it.

26 פברואר, 2015 06:23 PM

Oz Nahum

Simple Multiprocessing Task Queue in Python

Yet another tutorial about Python's multiprocessing. What make this one different? Well, it's based on a real like example and show what is going on behind the sceanes on your Linux host. ... continue reading...

26 פברואר, 2015 06:01 PM