‏הצגת רשומות עם תוויות תיכנות. הצג את כל הרשומות
‏הצגת רשומות עם תוויות תיכנות. הצג את כל הרשומות

יום שני, דצמבר 06, 2021

אל תסמכו על berilios / github או sourceforge ועשו fork עצמאי

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

הסיפור הוא בספריית GPL בשם OpenBlox, הספרייה הייתה קיימת בשנת 2008 ב sourceforge , עם השנים הפרוייקט נסגר וככל הנראה נמכר לחברה אחרת (F5), הפרוייקט המקורי והפתוח נסגר והוחלף בפרוייקט בשם אחר. 

במונחי אינטרנט מדובר כמעט בארכיולוגיה, במציאות אני לא מצליח למצוא את הקוד המקורי. 
קבצי קוד המקור הארוזים בzip יפה אינם , waybackmachine אינו מכיל את המידע שאני צריך (יש את דף הפרוייקט אבל לא את קוד המקור לצערי). 
 
הצלחתי בדרך לא דרך להשיג כמות גדולה של קבצי מקור (אבל רק קבצי header) של הפרוייקט אבל עדיין חסר לי את הרכיב שמייצר את tgl.lib (אם למישהוא יש את גרסת ה GPL באזור גירסה 2.7 יויכול לשתף אני אודה לו מאוד).

למדו מהכישלון שלי , וודאו שיש לכם מזלג/גיבוי של הפרוייקט שאתם צריכים.

יום ראשון, יוני 28, 2020

DBUS_SESSION_BUS_ADDRESS is no longer unix:path=/run/user/$(id -u)/bus

לאחר ששידרגתי את systemd  ו plasma גיליתי שצורת משתנה הסביבה DBUS_SESSION_BUS_ADDRESS השתנתה,  וחלק מהתסריטים שלי כבר לא יכולים לשלוח התראות לסביבה הגרפית.

בעבר המשתנה היה פשוט :

DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus

אבל עכשיו הוא קיבל פורמט אחר   :

DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-RANDOM,guid=UUID

הפתרון הנוכחי שלי הוא לנסות לגלות את משתנה הסביבה מ plasma :

eval $(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u username plasma_session)/environ ) 


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




השימוש בתוך אחד מהתסריטים שלי  נראה כך :

#Send on screen notification when doorbell notification had arrived
#Copyright (c) 2017 Boris Shtrasman
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:

#The above copyright notice and this permission notice shall be included in all
#copies or substantial portions of the Software.

#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
#SOFTWARE.

function notify_all_users()
{
     users=($(who | sed -nr "s/([a-z]*)[ \t]*.*\((:[^)]+)\).*/\1,\2/p" | sort|uniq))
     summery=$1
     text=$2
     for i in "${users[@]}"
     do
        user=$(echo $i | cut -d',' -f1)
        [ "root" == $user ] && continue
        screen=$(echo $i|cut -d',' -f2)
        id=$(id -u $user)
        #begin with a pre systemd 245 value
        DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$id/bus
        #get dbus for plasma
        [[ ! -z "ps aux | grep plasma_session|grep -vvv grep" ]] && eval $(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u user plasma_session)/environ )
        #get dbys for gnome sessions
        [[ ! -z "ps aux | grep gnome_session|grep -vvv grep" ]] && eval $(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u user gnome_session)/environ )
        #send an alert for each user that a door bell had been activated , 
        screen -Dm sudo -u $user  /bin/bash -c "DISPLAY=$screen DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS  /usr/bin/notify-send -t 15000 -i /usr/share/home/doorbell.png -u critical \"$summery\" \"$text\""
    
     done
} 

יום שישי, דצמבר 08, 2017

בדיקת חתימה דיגטלית על PDF

עריכה: הפוסט המקורי לא הציג ש Adobe Acrobat reader ככלי שיכול לפתוח קבצי PDF ויכול לאמת חתימות, זו היתה שגיאה ולמעשה יש חתימות שאקרובט רידר יכול לזהות כאשר תוכנות קוד פתוח אינן יכולת לאמת או לזהות. אינני נוהג להתקין תכונות שאינן חופשיות ולכן תוכנה זה לא נבחנה כלל בפוסט המקורי.

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

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

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

לקבצי PDF יש סטנדרט  שמסביר איך חתימה צריכה להראות ודוגמה למסמך חתום ניתן לקבל כאן.

כאשר מקבלים מסמך שנושא את ה"חותמת דיגיטלית" אפשר לבדוק בקלות אם יש חתימה  ע"י הפעולה הבא :

user@pc:~$pdfsig SampleSignedPDFDocument.pdf 
Digital Signature Info of: SampleSignedPDFDocument.pdf
Signature #1:
  - Signer Certificate Common Name: John B Harris
  - Signing Time: Jul 16 2009 17:47:47
  - Signature Validation: Signature is Valid.
  - Certificate Validation: Certificate has Expired
אם נערוך את המסמך נראה שהחתימה נשברת :

user@pc:~$pdfsig SampleSignedPDFDocumentWithChange.pdf 
Digital Signature Info of: SampleSignedPDFDocumentWithChange.pdf
Signature #1:
  - Signer Certificate Common Name: John B Harris
  - Signing Time: Jul 16 2009 17:47:47
  - Signature Validation: Digest Mismatch.

מסמך שיקרי לעומת זאת יתן :
user@pc:~$
pdfsig stupid_site_cant_handle_signatures.pdf 
File 'stupid_site_cant_handle_signatures.pdf' does not contain any signatures


ישנם מקרים בהם poppler לא יזהוא חותמת דיגילית על המסמך, ויש לנסות לבדוק עם Adobe Acrobat Reader אם יש זיהויי חתימה תקין בקובץ. אני יודע שזה לא תוכנה חופשית אבל עדיף להיות חכם מאשר צודק במקרה הזה.

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

לצערי חלק מהתוכנות איתן אני פותח את  ה PDF לא נתנו לי מידע פשוט בצורה טובה למה שחתום ומה לא ומה.

מע שעשו את העבודה אצלי היו:

LibreOffice-Writer - מציג את החתימה בצורה ברורה, מציג מידע על החתימה עצמה , כאשר המסמך נערך מעיף את הטענה כאילו המסמך חתום.

ואלו שכשלו :

אני מצפה שיהיה משהוא דומה להנחיות של אדובי לאיך להציג מידע על חתימה (עמוד 7 פה), רשימת התוכנות הבאה כשלו בצורות שונות לתת את המידע על מי חתם והאם החתימה אוטנטית (המסמך לא עבר שינוים לאחר החתימה):

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



okular  - לא מציג מידע על החתימה בצורה ברורה (מדביק את החתימה על המסמך) - לא נכשל או מודיע כשהמסמך עבר עריכה

xpdf - לא מציג מידע על החתימה בצורה ברורה (מדביק את החתימה  על המסמך) -   או מודיע כשהמסמך עבר עריכה
mupdf -  לא מציג מידע על החתימה בצורה ברורה (מדביק את החתימה  על המסמך) -   או מודיע כשהמסמך עבר עריכה
scribus - לא הצליח לפתוח כלל.

והכי גרוע :

firefox Quantum  -  לא מציג מידע על החתימה כלל. למה הכי גרוע ? כי זה הדפדפן שאני משתמש בו הכי הרבה ואני בדר"כ סומך עליו פשוט לעבוד.

לדעתי עצם זה ש okular ו mupdf פשוט מציגים את החתימה על המסמך ולא מציגים בצורה ברוה את המידע במקום אחר , מאפשר למסמך להדביק תמונה שאומרת שהמסמך חתום ללא שום מידע ויזואלי שזה לא חתום באמת. אולי באמת עדיף המצב של פיירפוקס שהוא כושל טוטאלית להציג חתימה במקרה כזה.

המצב של firefox 57 פשוט בדיחה.

היום כאשר יש אפשרויות כל כך פשוטות להוסיף חתימה או לחתום על מסמך שדורש חתימה , אין הרבה תירוצים למה שהמסמך לא יהיה אוטנטי .

יום שישי, אפריל 22, 2016

תקלות קידוד שפה בבסיס נתונים PostgreSql.

תקלות קידוד שפה בבסיס נתונים  PostgreSql .

על מנת להקל על הקורא דבר ראשון אם אתה רוצה להמנע מחיים קשים בהקשר של קידוד (ואתה לא על  SQL Server ) המנע מהתקנת השרת על וינדוס. אם אתה לא יכול לפחות המנע ממה שהוא לא SQL_ASCII והשתמש רק בשפה האנגלית.

אם אתה בוחר להתקין שרת בסיס נתונים על וינדוס או שאתה בוחר להשתמש בשפה שאינה אנגלית (אמריקאית) צפה לפגיעה.

הקורא הממוצע ישאל מה יש לכותב כנגד שפות שהן לא אנגלית אמריקאית ?

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

מדוע אני בתור איש וינדוס אומר להמנע משימוש בוינדוס כמערכת עבור בסיס נתונים במקרה הזה ?
התמיכה בקידודים ו locale שאינם en_us לדעתי לוקה בחסר, כברירת מחדל אין תמיכה ביוניקוד (צריך להריץ chcp 65001 בשביל להפעיל תמיכה למשל ביניקוד).

כאשר אנו מעבירים מידע  בין תוכנת לקוח לשרת  -  אנו  כפופים  לסוג הקידוד של מערכת הפעלה (מה שידוע כ code page) למאפייני השפה הנוכחים (locale) אופי קידוד המידע שיועבר ממערכת ההפעלה של הלקוח , אופי קידוד המידע בצד שרת ברמת הצד המקבל, אוקי קידוד המידע ברמת מערכת ההפעלה בצד המקבל , אוקי קידוד המידע בתוך בסיס הנתונים עצמו.

בעייה קלאסית כשמתקינים בסיס נתונים היא שימוש בשפה שאינה אנגלית ו Collate ברירת מחדל.

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

סיבה קלאסית היא הסתמכות על הקידוד מערכת ההפעלה ושימוש בקידוד ברירת מחדל, כשאנו למשל מדברים על עברית זה יכול להיות : UTF16* , ISO-8859-8, UTF8, CP1255,CP 862 ,ISO646.

ממה שאני ראיתי לרוב באפליקציות מהעשור האחרון דובר על CP122 ו iso8859-8 (לא נתקלתי במצב הגיוני של UTF16 או 8 כברירת מחדל עד היום).

בעולם הוינדוס בשביל לגלות במה משתמשים נשתמש בפקודה CHCP בשביל לגלות על איזה קידוד נמצא המשתמש בחיבור הנוכחי (session).

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


אם יש לנו גישה לקוד המקור נוכל להגדיר את הקידוד ברמת ה session (במקרה של ODBC) -
לדוגמה עבור PG ניתן להגדיר את הקידוד בצורה הבאה :

"SET client_encoding= 'UTF8'"

ואז לשלוח את המידע כשהוא עבר קידוד ל UTF8 (כל מחרוזת שנשלח צריכה לעבור קידוד ישירות ל UTF8 לפני ההגעה לקו)

פתרון נוסף הוא בחירת הקידוד ברמת החיבור בהנחה שהדריבר שאנו עובדים איתו תומך בunicode :

std::string url = "odbc:postgresql://url:ip/databse&client_encoding=UTF8"

חשוב לציין שאם מחרוזת החיבור נובעת מ DSN אז אפשר לבצע את ההחלפה גם בתוך ה DSN עצמו.

במידה ומשתמשים ב DSN תחת FreeTDS שם הפרמטר הוא ClientCharset והקידוד הוא לפי iconv ובגרסה הקניינית שם הפרמטר הוא Charset.
אצל אורקל שם הארגומנט הוא DatabaseCharacterSet


במידה במידה ואנו עובדים עם קידוד פנימי של שני בתים (wchar_t/UCS2)  ולא יכולים לשנות את מחרוזת החיבור הוא להחליף את הדריבר הרגיל לדוגמה psqlodbc.so ל psqlodbcw.so) ולהתבסס על המרת ברירת מחדל (בגרסאות ישנות של posgresql הפתרון היה פשוט להשתמש ב UCS2 ל UCS2 אם גם השרת וגם הלקוח הם עובדים על וינדוס).

לפעמים נתפתה פשוט תמיד להשתמש ב UTF8 תמיד ולצפות לטוב, הבעיה (אהם פרל אהם פרל) שלא כל השפות והדריברים תומכים בהמרה בין יוניקוד לשפה הנדרשת (EUC_JP לדוגמה) ואז נצטרך לבצע את ההמרה או באפליקציה שלנו או ברמת הדריבר או לבקש מבסיס הנתונים שלנו לבצע המרה.

המרה  ברמת הפעולה בבסיס הנתונים תראה בערך כך :

convert ( text , 'sourceencoding' , 'destencoding')

הממרה ברמת השפה איתה אנו משתמשים תראה בערך כך :

Perl:
$internalEncoding = decode( 'iso-8859-8', $var );
$result = encode( 'utf-8', $internalEncoding );
Java:
Charset utf8 = Charset.forName("UTF-8");
Charset iso8859_8 = Charset.forName("ISO-8859-8");
CharBuffer data = iso8859_8.decode(inputBuffer);
ByteBuffer output = utf8.encode(data);


iconv - C:

iconv_t cnv = iconv_open("UTF-8", "ISO_8859-8"); if (-1 == cnv) { return ; }
int ret = iconv(cnv, &text_in_8859_8, &length_of_text_in_8859_8, &text_in_utf8, &length_of_text_in_utf8);


יום רביעי, מרץ 30, 2016

שוב פעם טעו בתאריך ?


לפני זמן מה השתעשתי וצחקתי שWin10 כנראה תהיה מערכת ההפעלה שתרגום לאנשים לעבור ללינוקס. פשוט כמות הצרות שהמערכת עושה לוינדוס גורמת לsystemd להראות כמוצר טוב.

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

ע"פ פרסומים זרים מדובר על subsytem שלם (בדומה ל win32 ? ) שיש כאלה שטוענים שיאפשר הפעלה של קוד לינוקסאי (לא קרנל לצערי) אני לא יודע אם זה לא בלון כמו Astoria או שזה יהיה ה wine של וינדוס.

אז מה זה אומר בשבילי ? 

כנראה אין יותר צורך או בעייה ב msysgit או סביבת GNU לוינדוס שאני כל הזמן ממליץ עליה. וכמובן שכנראה הרבה מאוד וירוסים הולכים לפגוע בנו. אבל מצד שני אם הפלאגינים הטבעיים ב VS2015 אינם מסוגלים להתמודד עם git כמו שצריך לצפות שמערכת זרה תעבוד זה פשוט יותר מדי.

גם אם תהיה יכולת הפעלת ELFים (ואני בספק שזה יעבוד) אני לא רואה שום יתרון של זה על gnuwin.


אבל לשפוט על ה"תאימות" של וינדוס עם פוסיקס כנראה שזה לא יעבור בשלום (עד היום אין תמיכה ב BSD סוקטס בתאימות למה שיש לנו בפוסיקס). גם SUA וגם התמיכה המפורסמת בפוסיקס ב 7 לא ממש תפקדה עבור הצרכים שלי.


 לא זה עדיין לא הראשון באפריל , זה נראה רציני....
 
 

יום רביעי, דצמבר 09, 2015

בחיאת העידכון

לפני תקופה מסוימת שיתפתי עם חברי את ההחלטה להפסיק לבצע עידכונים אוטמטיים על המכונות שלי ולהסתמך על התשתית בשביל שתבצע לי אבטחה (IDS וחבריו).

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

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

מדובר על חיבור קווי של 15 מסל"ש , כונן SSD ו 16 ג"ב ראם כמה זמן אי עבודה ייקח Serivce pack לסביבת הפיתוח VS 2015 ?

הורדת התוכן עצמה לקחה בערך כ 15 דקות (שלב ה Acquiring) ואז הגיע האבל , שלב ה Applying מהפעלה הראשונה מהלך של שני איתחולים , Repair (כי היתה קריסה בדר"כ) הציג downtime של 5 שעות עכשיו בו ונכפיל את זה עבור כל מחשב פיתוח.

‎רק בשביל לסבר את האוזן זה התקנה שמכילה רק Visual C++‎ לא משהוא מיוחד (רק 8 ג"ב עידכון נדרש).

לפי מה שאני מבין כל מי שדיברתי איתו בימים האחרונים שמשתמש ב Win7 עובד ב C++‎ ומתקין את  Visual Studio 2015 Update1‎  קיבל משהוא דומה Downtime של רבע יום ומעלה ותהליך שדורש ביצוע repair כי יש ריסוק בדרך.

למזלי אני עדיין לא ב Win10 אז אם יש פה משהוא שיש לו Win10 ממליץ בחום רב לפני העדכון להסיר כל תוסף שקיים שם (לפי קולוגות זה הדבר היחידי שאפשר להתקין VS2015) לשדרג ואז להתקין שוב.

יום רביעי, ספטמבר 30, 2015

רעידת אדמה בשבילי תחת cppcon

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

מי שיצא לו לדבר איתי בתקופה האחרונה על VS2013 ו meta precompiler תלויי דמויין יודע את דעתי על SAL ודומיו.

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

 עכשיו למה GSL והצעה של סטראסטורף בכלל חשובה ? כי ההנחיות מפורסמות כפרוייקט קוד פתוח (ומבקשים הצעות והערות) אני לא יודע אם יתקבל משהוא בסדר גודל של CPP coding standars (דרך אגב ממליץ בחום) אבל החשיבות היא שיכול להיות שזה ידחף כמו שjavadoc נדחף בזמו לתיעוד.

והרב מודה לכם על מה שתוסיפו שם.

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


אני כנראה אצטרך לאכול את הכובע עוד מעט, כי אם הבנתי נכון מייקרוספט הולכת לשחרר את כלי (רעיון) האנליזה שלהם ויכול להיות שאנשים ידחפו את זה לתוך gcc ודומיו (ואז אני צריך לבחור כובע בצהריים). אני חייב להזכיר את הבעייה של הכלי ב VS שהוצג - בדיקת אנליזה של תוכנית הדוגמה לקחה כ 25 שניות קמפול ללא אנליזה לקח מספר בודד של שניות (בממוצע כשלוש שניות. זה אמנם לא נשמע הרבה אבל תחשבו לרגע על קוד בייס קצת יותר גדול מקובץ אחד ואני ראיתי במציאות אנליזה שלוקחת כ20-30 דקות לפרוייקט, וזה מתבצע בכל בנייה כל פעם.



שמחתי לראות שכשאני עובר על חלק מההרצאות שאני משתמש בהם היום בלי להיות מודע שזה טוב כשאני יכול ואני חייב להגיד תודה לספר המדהים C++ Concurrency in Action ביחד עם מעבר על gotw וכמובן שימוש ב VS. מצד שאני התאכזבתי מעצמי שלמרות אני עוקב אחרי C++11/14 אני רואה שאני עושה דברים רעים ופשוט לא מודע לדברים שפורסמו לפני כמה שנים טובות. במהלך ההרצאות הבנתי כי לפחות בחלק מהספריות אהיה מנוע להשתמש בכלים כמו array_view ו not_null למה ? כי אם אני אציג קוד בסגנון של
foo({ptr,size});
אנשים ישנאו אותי, כמובן שיש הרבה דברים שאני לא אוהב זה הרעיון של כתיבה שונה (שימוש במאפיינים בשביל להכריז כי מקטע קוד לא ייבדק) :

[[command(operator)]] memcpy(dst,src,size);

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

יום שלישי, ספטמבר 29, 2015

מה לבקש מאיש ה IT לאישור

גיא שאל אותי על איזה כלים הייתי ממליץ לקבל אישור תאגידי להכנסה בסביבת windows, ובגלל שזה ארוך ואולי עוד מישהוא ישאל יצטרך אז בבקשה. 



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

בחשיבות יורדת  - כלי ארגז כלים -

אשרור על מה שיש בתוך gnuwin (תוכנה חופשית) - כמעט כל מי שנגע בסביבת nix יהנה (וידע להשתמש) ב sed/grep/wget וחבריהם. (כמעט) כל אחד מהבינריים שם הוא self contained מה שלא מחייב התקנות נוספות.

telnet - רכיב וינדוס אינו תוכנה חופשית או קוד פתוח, מאפשר דיבוג לרכיבים.

openssl (קוד פתוח , תוכנה חופשית) - משומש כאשר יש צורך לדבג תקושרת ידנית תחת רכיבי הצפנה , מאפשר לבדוק מבנים בינרים באמצעות שימוש ב asn1parser.

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

wireshark - (תוכנה חופשית) פריימורק הצגת מידע וקבלתו ממגוון אמצעים שמעבירים תקשורת החל מכרטיסי רשת ועד קו USB.

nmap  -(לא ברור האם תוכנה חופשית) (ולא לשכוח את ספריית התסריטים) הוא בין הכלים הטובים ביותר לבדיקות הקשורות ברשת.

winmtr  - מימוש של mtr.

notepad++ (קוד פתוח) - ביחד עם פלאגין בשם hexeditor - כנראה אחד מעורכי הטקסט הטובים שנתקלים בהם לאחרונה.
msysgit - מערכת ניהול גרסאות  git  ( וגם אחרים כמו svn) מושחת גם perl ו bash for windows.

firefox .

כלי בנייה -

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

cmake

(Autoconf ו m4 כבר מגיעים בתוך gnuwin ).

יום שבת, אוגוסט 29, 2015

תודה לחברת הסלולאר שהחזירה אותי לשנות ה 90

אני חייב להגיד תודה ענקית לחברת הסלולאר לה אני מנויי, בגלל תקלה אצלה (יש כאלה שמאשימים את ה HLR) לא היה לי חיווי שיחות נכנסות לא היו SMSים ולא היו MMSים, במהלך התהליך הייתי כה נואש שאף ניסיתי לנסות לתקשר באמצעות MMS ל מייל ונאדה. ממש חזרתי לשנות ה 90 העליזות.


אבל הקטע המדהים בכל הנושא הזה שיכלתי להוציא שיחות החוצה, ורק באמצעות חברי שיצרו איתי קשר ב jabber גיליתי על התקלה.


ביחד עם המזל המדהים שלי (טוב נו ראיתי שידורים מדב קונף) גם חבילת הגלישה שלי הייתה על 0 "הורדת מהירות" - ולמי שלא נתקל באפקט של   "הורדת מהירות" :


מדובר על מצב בו אי אפשר להתחבר לאתר של ספק הסלולר שלך לבדוק מצב חשבון מהירות שנעה מתחת ל 64Kbps - אז כן ה RSSים עובדים אבל אין IMAP.

המהירות כל כך נמוכה שאתה משתעשע ברעיון של להרים שרת dialin להתקין של mgetty ו PPD הפעלת AutoPPP ורק אז להיזכר שאתה צריך ממשק טורי שימיר v34 ויהיה מחובר איכשהו לטלפון/ מחשב, וזאת בעקבות כי חברות הסלולאר חסמו CSD שמבוצע ע"י ATD  (אם יש משהוא שיודע איך להפעיל זאת מודה מראש). לפחות בסופ"ש חזר החיבור הנורמאלי.

אבל מה שהכי הרג אותי זה היה שירות הלקוחות המדהים :


אני : כאשר מתקשרים לקו שלי XXXYYYZZ נאמר כאילו אני לא זמין, אין לי בעייה להוציא שיחות באותו הזמן וחלק קטן מהשיחות אף הצליח להכנס.

שירות הלקוחות : בוצעו מספר ניסיונות היום 25/08/2015 ליצור עמך קשר, אך לצערנו שיחותנו נותרו ללא מענה.

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

יום שישי, אוגוסט 28, 2015

ייתוש שמפרסם הודעות

אחד הדברים החמים שיצא לי לעבוד בהם לאחרונה היא הטכנולוגיה ה"ישנה" בשם MQTT.
מדובר על פרוטוקול שמאפשר העברת הודעות עם overhead מאוד נמוך ושאחד הפיטצרים שלו הוא חיוויי הודעות.

כן כן אני יודע שב TCP יש retransmit, פה מדובר ברמת האפליקציה בלקוחות SOAP נאלצנו לייצר ACK מהלקוח לקבל תצורה כזאת בכל פעם ופה זה מגיע מובנה.

בשונה בפרוטוקולים כמו SOAP ב MQTT ניתן לבקש כי הודעת שרת תישלח רק פעם אחת , לפחות פעם אחת או בלי שום בדיקה.

כמשתמש קצה הדוגמה הקלאסית לשימוש ב MQTT היא ב facebook messanger (שם זה מגיע יחד עם thrift) או התקנה של ייתוש ולימוד שימוש בו.

מאוד בגדול ב MQTT מדובר בתוצרת מפרסם / מקבל ע"ג תור הודעות שמנוהל ע"י שרת מרכזי.

מאוד בגדול המערכת תורכב משלושה ישויות .

ברוקר - שרת שמקשר הודעות, פה מתנהל ניהול ה queue של ההודעות.
תוכנת פרסום - תוכנה שתודיע על קיום הודעה חדשה ושליחתה לברוקר.
תוכנת מקבל    - תוכנה שמושכת הודעות מהברוקר.

ה QOS עליו דיברתי מכיל שלושה ערכים אפשרים:

0 - אין שום אינדקציה לקבלת / שליחת ההודעה.
1 - פעם אחת לפחות (מחכה להודעת PUBACK)
2 - בדיוק פעם אחת.

בדומה למה שעושים ב REST יש endpoint שמציג מאפייני הודעות למשל עבור פייסבוק :

                /inbox
                /mercury
                /messaging_events
                /orca_presence
                /orca_typing_notifications
                /pp
                /t_ms
                /t_p
                /t_rtc
                /webrtc
                /webrtc_response

למה אני ממליץ על הייתוש (ואני שונא ייתושים) ולא אחרים ?

1. יש לו אחלה תיעוד
2. הוא מגיע מובנה בדביאן בלי שום דרישות מיוחדות.
3. הוא עובד בווינדוס


יום חמישי, אוגוסט 20, 2015

בדיקות דרך קומפילציה

לא מזמן יצא לי לדבר על בדיקות עם ידידי משכבר הימים ויצא לי להציג שיטות תאומות שאני אוהב לדחוף -

היום הרבה מידידי משתמשים בכלים מצויינים כמו ג'נקינס ו TFS (יש הרבה אחרים אבל הרעיון דומה), מאוד בגדול מדובר על מערכות שדוגמת גרסה מסויימת מריצה מספר בדיקות ונותנת את תוצאת הבדיקות (אצלי המצב טיפה שונה כי יש פתרון in-house) ומדווחת למתכנתים .

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


#include <iostream>
#include <gtest/gtest.h>

struct foo
{
  int random(){return 4;};//chosen by fair dice roll.
                          //guarnteed to be random :P
                          //by xkcd 221

};



TEST(foo, random) {
  foo f;
  EXPECT_EQ(0, f.random());
}



int main (int argc, char **argv)

{
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

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

הבעייה בגישה של בדיקה בזמן ריצה (אפילו בתחילת ריצה) או בזמן בנייה כטסריט חיצוני  היא שזה עדיין משאיר פתח עצום למתכנת לעשות קומיט לדחוף אותו לרפוסטורי כשהוא לא נבנה (אני באמת רוצה לראות את איש ה IT שיצליח לדחוף הוק שמבצע בנייה על מכונה של מפתח שתמנע ממנו לעשות push אם בנייה נכשלת).

עכשיו בגלל שאני חי בעולם יחסית טוב (בכל זאת כותב בשפות מקומפלת) יש לי אפשרות נוספת שהתרגלתי להשתמש בה - כתיבת בדיקות שמכשילות קומפילציה שזה בשונה מבניית פרוייקט כן מתקבלת כקרס (גם ב git ו גם svn) בצד מפתח.

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

דוגמה קלאסית למטה דטה של מבנים (שתכשיל קומפילציה ) :



#include <iostream>
#include <cstddef>
#include <type_traits>

struct mytype_t
{
   //these are just example for some fields 
   int field1;
   int field2;

//   int non_declared_field_in_cmo_field_table_name;//this field had not been declared in cmo_field_table_name

   char y[3];
};

struct metadata_t
{
   size_t size;       
   size_t offset;     
   size_t allignment; 
   const char *  name;

} ;

//we have macro that fill metadata_t
//

static constexpr const struct metadata_t cmo_field_table_name[] = 
{
  {sizeof(mytype_t::field1),offsetof(mytype_t,field1) , std::alignment_of < decltype (mytype_t::field1 )> :: value,"1"},
  {sizeof(mytype_t::field2),offsetof(mytype_t,field2) , std::alignment_of < decltype (mytype_t::field2 )> :: value,"bla"},
  {sizeof(mytype_t::y),offsetof(mytype_t,y), std::alignment_of <decltype( mytype_t::y) > :: value,"2"},
};



//We declare a type that will fail compilation in case
template <bool>

struct check_struct_for_missing_field
{

};

template <>

struct check_struct_for_missing_field<true>
{
 //I named this field as field and not anything else so the compiler error will be more understandble 
 enum {field = 0};
};


//the magic start here 
//a recursive defintion that check on compile time if all the previous fields had been declared correctly
//in case of non declared fields this will fail compilation and will give us an error that will prevent a person commiting errosly like this mornign
//
//compile_type_check.cc: In instantiation of ‘struct check_if_all_fields_for_struct_correctly_declared_argument_is_field_number<((const metadata_t*)(& cmo_field_table_name)), 2>’:
//compile_type_check.cc:74:178:   required from here
//compile_type_check.cc:62:9: error: ‘field’ is not a member of ‘check_struct_for_missing_field<false>’
//    enum {check =  check_struct_for_missing_field < check_if_all_fields_for_struct_correctly_declared_argument_is_field_number < ptr,index_in_ptr - 1> :: value == ptr[index_in_ptr].offset  > ::field};
//             ^
//             compile_type_check.cc:74:1: error: static assertion failed: missing fields in tab
//              static_assert(check_if_all_fields_for_struct_correctly_declared_argument_is_field_number <cmo_field_table_name, sizeof(cmo_field_table_name)/sizeof(cmo_field_table_name[0]) -1 >::value == sizeof(mytype_t) , "missing fields in tab");
//
//
template < const struct metadata_t * ptr, int index_in_ptr>
struct check_if_all_fields_for_struct_correctly_declared_argument_is_field_number
{
  //incorrect declartion (type mismatchs) are found here
  //a correct offset of field N is  (alligment + size + offset ) for field N - 1
  enum {value =
        (
          ( ptr[index_in_ptr].allignment != ptr[index_in_ptr].size)?

            ptr[index_in_ptr].size + ptr[index_in_ptr].allignment
            :
            ptr[index_in_ptr].size)
            //this will iterate for the previous fields until the first declared in ptr
          + check_if_all_fields_for_struct_correctly_declared_argument_is_field_number<ptr,index_in_ptr-1>::value};
   //in case we have a missing field the next will fail compilation saying : 
   //
   enum {check =  check_struct_for_missing_field < check_if_all_fields_for_struct_correctly_declared_argument_is_field_number < ptr,index_in_ptr - 1> :: value == ptr[index_in_ptr].offset  > ::field};



};

//this is the final step of fields (the zero in the index

template <const struct metadata_t * ptr>

struct check_if_all_fields_for_struct_correctly_declared_argument_is_field_number <ptr,0>
{
 public:
   enum {value = //cmo_field_table_name[0].offset + 
        ( ptr[0].allignment != ptr[0].size)? ptr[0].size +   ptr[0].allignment :ptr[0].size
       };
};


static_assert(check_if_all_fields_for_struct_correctly_declared_argument_is_field_number <cmo_field_table_name, sizeof(cmo_field_table_name)/sizeof(cmo_field_table_name[0]) -1 >::value == sizeof(mytype_t) , "missing fields in tab");



int main(int argc, char *argv[])
{
  for (auto & r: cmo_field_table_name)
  {

    std::cout << "name:" << r.name<< " offset:" << r.offset << " allignment: " << r.allignment << " size:" << r.size << "total: " << r.size + r.allignment << std::endl;

  };

  return 0;

};

בחרתי ב C++  כי לדעתי היא פשוטה מספיק להבנה אבל דבר מאוד דומה ניתן לבצע גם בשפות אחרות.

JAVA: כן אני זוכר את הנושא של המרה לobject ובעיית הstatic הנקודה היא שימוש בטיפוסי הנתונים כמשתנים.

C: יחי המקרו ! יאפ בנייה על בסיס מקרו.

FPC: אם משהו עדיין משתמש בזה - "

FPC 2.4.0 is neither complete nor practically usable yet. Until that is so, templates can be used." אבל אני די בטוח שיש פתרון אחר.

הכשלת קימפול בגלל בדיקות מאפשרת יכולת נבוט טובות יותר ואני מאמין עם ערך wtf/minute נמוך יחסית.

יום ראשון, דצמבר 15, 2013

משלוח קבצים ב MMS

נאלצתי לבצע העברת קבצים די גדולה לפני זמן מה וחבילת האינטרנט בנייד הסתיימה.
מכיוון שאני די תקוע עם linmodem ואין לי יכולת לפתוח קישור ע"ג gnuradio גמלה בלבי ההחלטה להשתמש בMMS בשביל לשלוח את הקבצים.

מה שעשיתי היה להתקין את python-messaging ולכתוב תסריט פשוט שיבצע שליחה של הקבצים.
בחרתי לשלוח ע"ג תמונה בגלל היכולת שלgif לאחסן קבצים אחרים ועדיין לעבור תחת הידיים של האנטיספאמרים הידועים לי.

תוצאות:

בדקתי עם מספר ספקים ושליחה של מ"ב ספורים (עד 3 לקובץ מקודד) עברה בצורה תקינה.

לא הייתי ממליץ לשלוח ג"ב בצורה כזאת (כי בכל זאת MMSים עולים כסף - אם אני מבין נכון זה נע באזור ה60 אגורות ליחידה) ואצל חלק מהמפעילים גודל ההודעות מתומכר גם כן.

תזהרו לא להספים או לשלוח לרשומות תפוצה (זה לא שימוש הוגן והספק כנראה ינתק אותכם).

דברים שצריך לדעת לפני :

הapn
הsmsc

התסריט עצמו:

#!/usr/bin/python
 

from messaging.mms.message import MMSMessage, MMSMessagePage

from argparse import RawTextHelpFormatter
import argparse

import socket    
import cStringIO # for the response

import sys,os #needed for file size + exit
import errno  #error handling
import getpass#to log the user name

parser = argparse.ArgumentParser(description='Send mms image to an email or a PSTN',formatter_class=RawTextHelpFormatter,
     epilog="""
 Scrapped from the docs by Boris Shtrasman (license GPLv2 as the python-messaging)

 1. In case you don't have a public access to mmsc (like I do): 

 get a cable and connect your phone to the pc,find out what are your mmsc and apn
 
 my mms apn is mms.provider.fr (look for mms apn configuration at your provider.tld)
 wvdial.conf example: 
    [Dialer mms]
    Phone = *99***1#
    Username = fillmeifneed #if your provider uses a username for mms fill it up
    Password = fillmeifneed #if your provider uses a password for mms fill it up
    Stupid Mode = 1
    Dial Command = ATDT
    Modem = /dev/ttyACM0
    Baud = 460800
    Init2 = ATZ
    Init3 = ATE0V1&D2&C1S0=0+IFC=2,2
    ISDN = 0
    Modem Type = Analog Modem
    Init5 =AT+CGDCONT=1,"IP","mms.provider.fr";
 
 run wvdial 
 ~/sudo screen wvdial mms
 
 You would need to check your routing as both the mms provider and your internet provider would\
 give you an ip address.
 
 2. 
 
 find out what is the mmsc address ,don't relay on name as some provider will not resolve it in my example it is 192.168.10.200
 every mms provider has it own port mine used 8080 (other use 80, 9090 and many others)

 In order to pass normal files zip them and add into a gif : 
    cat ~/somegif.gif >> /tmp/tobesent.gif
    zip -0 archive.zip stufftosend/* 
    cat ./archive >> /tmp/tobesent.gif
    
 to send to an email to user at example dot  net when your provider uses email  : 
    send -s 192.168.10.200 --port 8080 -i /tmp/tobesent.gif -d "user@example.net"  -a /mmsc -b "rename the gif to zip"
 to send an email to a phone number 
    send -s 192.168.10.200 --port 8080 -i /tmp/tobesent.gif -d "+3362123123"  -a /mmsc -b "rename the gif to zip" """)
     
     
parser.add_argument('-s','--mms_host', help='mmsc host',required=True)
parser.add_argument('-p','--port',help='mmsc port',type=int, required=True)
parser.add_argument('-i','--input_file',help='file to send as image', required=True)
parser.add_argument('-d','--destination',help='destination in PLMN or email', required=True)
parser.add_argument('-a','--mms_address',help='the mms address to use (commenly just /) some will have http://ip:port/path', required=True)
parser.add_argument('-c','--cc',help=' CC optional ', required=False)
parser.add_argument('-b','--subject',help=' subject  ', required=False)

args = parser.parse_args()

cc_destination = ''
if  args.cc: cc_destination = args.cc
subject = ''
if args.subject: subject=args.subject

print "As you wish %s, I will send the file:%s[%u kb] to %s and cc %s subject (%s)" % (getpass.getuser(),args.input_file,os.stat(args.input_file).st_size / 1024,args.destination,cc_destination,subject)
  
mms_page = MMSMessagePage()
mms_page.add_image(args.input_file)

mms = MMSMessage()
mms.headers['To'] = args.destination
mms.headers['Cc'] = cc_destination
mms.headers['Message-Type'] = 'm-send-req'
mms.headers['Subject'] = subject
mms.add_page(mms_page)
print "will encode '%s' (preparing what would be sent to the destination)" % args.input_file
encoded_mms = mms.encode()
print "message had been encoded"
mmsc_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "connecting to %s:%u" % (args.mms_host , args.port)
try:
  mmsc_socket.connect((args.mms_host, args.port))
  
except socket.timeout:
  print "A timeout to %s:%d was set, make sure you can access it (routes, packet loss etc)" % (args.mms_host, args.port)
  sys.exit()
except KeyboardInterrupt:
  print "Don't be so hard on %s:%d it should work ... " % (args.mms_host, args.port)
  sys.exit()
except socket.error as serror:
  if serror.errno == errno.ECONNREFUSED:
    print "your provider prevent accessing to this mmsc %s have you checked you are using the correct credntials ?" %  (args.mms_host, args.port)
    sys.exit()
  if serror.errno == errno.ETIMEDOUT:
    print "I'm sorry but you need to check your routes to %s, then check your fw doesn't block unreachable destination, when all fail contact customer service" % (args.mms_host)
    sys.exit()

  print "A timeout to %s:%d was set, make sure you can access it (routes, packet loss etc) (%s)" % (args.mms_host, args.port, serror.errno)
  sys.exit()

  
print "was able to connect to %s:%u" % (args.mms_host , args.port)
mmsc_socket.send("POST %s HTTP/1.0\r\n" % args.mms_address)
print "POST command sent to the server"
mmsc_socket.send("Content-Type: application/vnd.wap.mms-message\r\n")
mmsc_socket.send("Content-Length: %d\r\n\r\n" % len(encoded_mms))
print "an encoded mms is on the way to the server , please wait : as %d bytes are on their way to the server and that will take some time" % len (encoded_mms)
try:
 mmsc_socket.sendall(encoded_mms)
except socket.error as serror:
  print "Try to use a smaller file, or check your connection as I couldn't finish the transfer %s" % serror.errno
  sys.exit()
except KeyboardInterrupt:
  mmsc_socket.close()
  print "Don't be so hard on %s:%d it should work ... " % (args.mms_host, args.port)
  sys.exit()
  
print "encoded mms had been sent "
serverResponseStream = cStringIO.StringIO()

while True:
    data = mmsc_socket.recv(4096)
    if not data:
        break

    serverResponseStream.write(data)

mmsc_socket.close()
data = serverResponseStream.getvalue()
serverResponseStream.close()

print "PROXY RESPONSE", data

יום שישי, יוני 22, 2012

וחיו git ו svn ביחד

 יש לי התקנה שהיא יחסית נדירה, אני משתמש במספר מערכות ניהול גירסאות על המחשב שלי בו זמנית.
יש לי גם ניהול גירסאות מבוסס svn וגם ניהול גירסאות מבוסס git-svn, והחלק הבעייתי באמת מדובר על מספר גיגה בייתים של מידע תחת svn.

בפעם הראשונה שמנסים לעשות clone מגבלים שgit יוצא ללא שגיאה ומה שרואים היינו:

git svn clone -s https://ip/svn/project/trunk_name local_repo
rXXXXX = 231876121242148168246 (refs/remotes/git-svn)

אם ניכנס לתיקיה local_repo נראה שאין קבצים פרט לתיקיית .git, על מנת לפתור את הבעיה הזאת יש להריץ git svn fetch מתוך התיקייה שנוצרה ע"י git svn.
בחלק מהמקרים נאלצתי להריץ ידנית fetch עוד עשרות פעמים עד ש git הואיל בטובו להוריד את כל הפרוייקט, מדי פעם עדיף להריץ גם git gc (אחת ל 1000 גירסאות הספיק לי .


בעייה נוספת שניתקלתי בה היה יצאה של git תוך כדי clone ולאחר מכאן fetch או rebase:
fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
   Use '--' to separate paths from revisions
   log --no-color --no-decorate --first-parent --pretty=medium HEAD: command returned error: 128

הפתרון לבעיה זו הוא להשתמש ללא -s ולכוון ל svn trunk שצריך דוגמה :
git svn clone https://ip/svn/project/trunk_name/ local_repo

טוב בשעה טובה ומוצלחת הצלנו לעשות clone לפרוייקט הגדול שלנו איך ניתן לו לחיות ביחד עם svn באותה התיקיה ?  שימו לב שזה מתכון לצרות - אבל גם ללמידה.

לוקחים את תיקיית ה git שנוצרה (יש רק אחת ומושכים אותה לתיקיה הראשונה שנוצרת לכם ע"י svn ,
לדוגמה:


/opt/svn/bfs_patches$ ls -la
total 7816
drwxr-xr-x 15 boris boris    4096 Jun 21 18:49 .
drwxr-xr-x  3 boris boris    4096 Jun 21 18:21 ..
-rw-r--r--  1 boris boris     174 Jun 21 18:24 .buildpath
drwxr-xr-x  3 boris boris    4096 Jun 21 18:24 docgenerator
drwxr-xr-x  9 boris boris    4096 Jun 22 00:47 .git
drwxr-xr-x  3 boris boris    4096 Jun 21 18:51 2.6.38-bfs
-rw-r--r--  1 boris boris     517 Jun 21 18:24 .project
drwxr-xr-x  3 boris boris    4096 Jun 21 18:24 .settings
drwxr-xr-x  6 boris boris    4096 Jun 21 20:15 .svn



הוספתי את התיקייה .git לתוך תיקיות שהיו תחת svn, השלב הבא הוא לזכור שבכל פעם שאנחנו משנים קבצים ע"י svn לעשות :
  git  reset --hard && git svn rebase

שימו לב זה יעיף את כל השינוים המקומים שלכם בgit.
למה אני עושה את זה - אני עובד עם הרבה מאוד תוכנות ותסריטים שדורשות עבודה עם svn ולא יודעות להתמודד עם git. לכן כאשר אני מסיים איתן אני מריץ reset וחוזר לעבוד עם git.

יום שלישי, דצמבר 06, 2011

למה אתה משתמש ב WSDL ?!

היום בשעה טובה ומצלחת הבנתי למה הקוד שעובד לפי ה wsdl לא עובד:
פשוט השרת שעובד עם ה wsdl לא מתייחס לפי מה יש ב wsdl אלה רק למידע שהוא רוצה (וגם מניח שהשאר עושים זאת) :

המבנה :

<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="CALENDAR">
        <xsd:complexType>
            <xsd:sequence>
            <xsd:element name="SID" type="xsd:int" minOccurs="1" maxOccurs="1"/>
            <xsd:element name="COURSE_ID" type="xsd:int" minOccurs="1" maxOccurs="1"/>
            <xsd:element name="STARTDATE" type="xsd:dateTime" minOccurs="1" maxOccurs="1"/>
            <xsd:element name="ENDDATE" type="xsd:dateTime" minOccurs="1" maxOccurs="1"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>


ע"פ ההגדרה המבנה הוא :

[-]CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm]

אבל לא האיש שכתב את השרת החליט שהמידע צריך להתקבל בצורה :
DD/MM/CCYY

נשאלת השאלה : למה אתה מגדיר מבנה נתונים שהוא לא נכון.
אם מעבירים את המידע בצורה לפי ההגדרה אנו מקבלים ... נכון: unhandeled soap exception

ממשיכים הלאה יש תשובה שמשתמשת בשם שנותן הרגשה שמדובר בזמן :


<xsd:element name="STARTTIME" type="xsd:string" minOccurs="1" maxOccurs="1"/>
<xsd:element name="ENDTIME" type="xsd:string" minOccurs="1" maxOccurs="1"/> 

ונחשו איזה מידע אני מקבל ?

<STARTTIME>1/1/1900 8:00:00 AM</STARTTIME>
<ENDTIME>1/1/1900 11:00:00 AM    </ENDTIME>

השאלה הראשונה שנשאלת למה יש תאריך (אם לשדה קוראים time) . השאלה השנייה למה יש רווחים בסוף enddate.
מה שעשיתי בסוף זה אוטמט שיודע לזהות מבני הצגת תאריך וזורק את כל ה whitespaces

בדוגמה הזאת רואים סיבה מצויינת למה אנו נאלצים לעבור ולעבד את המידע שנוצר מ   gsoap / wsdl2javakdoap ולעבור בצורה ידנית על כל פונקציה ולהתאים לאנשי ה .NET

השיטה שמצאתי כמתאימה לזיהוי בעיות כאלה היא שימוש ב curl / telnet (ובאמת תתפללו שאין איזה שהיא מערכת שמחייבת הזדהות לא נורמאלית).

ב curl יש אפשרות לבדוק במה אנחנו תומכים (איזה סוג הזדהות )לדוגמה ב דביאן :

curl 7.21.7 (x86_64-pc-linux-gnu) libcurl/7.21.7 OpenSSL/1.0.0e zlib/1.2.3.4 libidn/1.22 libssh2/1.2.8 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap pop3 pop3s rtmp rtsp scp sftp smtp smtps telnet tftp
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz

הצעד הבא הוא ווידוא איזה סוג של מכשור יכול להתחבר לדוגאות :

appname/1.2 CFNetwork/485.10.2 Darwin/10.3.1
Zune/4.7
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5


רק לאחר שווידאתם שאפשר באמת לבצע את הפקודה באמצעות curl תתחילו לכתוב קוד (זה יחסוך לכם הרבה מאוד כאב ראש לאחר מכן).

יום שני, נובמבר 28, 2011

Inserting LONGVARBINARY into MS SQL Server

נתקעתי בבעיה קטנה של המרת קוד ישן שעובד עם freetds + unixodbc בשביל להכניס מידע לבסיס נתונים של MS SQL.
כזכור הסוג IMAGE יורד בהקדם אז צריך לעשות המרה של הקוד שמטפל בזה לאחרים.
אז הנה דוגמה לשימוש ב כfreetds ע"ג odbc בשביל לשלוח מידע שיכול לאחסן קבצים.


/*

    Copyright 2011  Boris Shtrasman boris sh 1983 at gmail dot com

    Permission to use, copy, modify, and distribute this software
    and its documentation for any purpose and without fee is hereby
    granted, provided that the above copyright notice appear in all
    copies and that both that the copyright notice and this
    permission notice and warranty disclaimer appear in supporting
    documentation, and that the name of the author not be used in
    advertising or publicity pertaining to distribution of the
    software without specific, written prior permission.

    The author disclaim all warranties with regard to this
    software, including all implied warranties of merchantability
    and fitness.  In no event shall the author be liable for any
    special, indirect or consequential damages or any damages
    whatsoever resulting from loss of use, data or profits, whether
    in an action of contract, negligence or other tortious action,
    arising out of or in connection with the use or performance of
    this software.

*/
#include <stdio.h>
#include <sql.h>
#include <sqlext.h>

#define TABLE_NAME "binary_v3"

static void extract_error(
    char *fn,
    SQLHANDLE handle,
    SQLSMALLINT type);



int main()
{
   #undef UNICODE /* for the Win ppl */
   SQLHENV henv;
   SQLHDBC dbc;
   SQLHSTMT stmt;

   RETCODE retcode;

   SQLLEN cbTextSize, lbytes;
   PTR pParmID;
   char binary_data[8024]="";

   memset(binary_data,0,sizeof(binary_data));
   binary_data[1] = 5;

   //lets define some strage number for batch  
   SDWORD batch_size = sizeof(binary_data) - 1024;

   // Allocate the ODBC environment and save handle.
   retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) 
   {
      printf("SQLAllocHandle(Env) Failed\n\n");
      goto cleanup;
   }

   // Notify ODBC that this is an ODBC 3.0 app.
   retcode = SQLSetEnvAttr(henv, 
        SQL_ATTR_ODBC_VERSION,
           (SQLPOINTER) SQL_OV_ODBC3,
                SQL_IS_INTEGER);

   if ( 
       (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) 
   {
      printf("SQLSetEnvAttr(ODBC version) Failed\n\n");
      goto cleanup;
   }

   // Allocate ODBC connection handle and connect.
   retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &dbc);
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS))
   {
      printf("SQLAllocHandle(dbc) Failed\n\n");
      goto cleanup;
   }
     
   SQLCHAR odbc_dsn_string_dump[255];
   SQLSMALLINT odbc_dsn_string_dumpLen;

   retcode = SQLDriverConnect(
           dbc,
           NULL,
           (SQLCHAR *)"Driver=FreeTds;"
                "SERVER=192.168.1.2\\SQLEXPRESS;UID=sa;"
                "PWD=pwd;DATABASE=db",
           SQL_NTS,
           odbc_dsn_string_dump,
           sizeof(odbc_dsn_string_dump),
           &odbc_dsn_string_dumpLen,
           SQL_DRIVER_COMPLETE);
   
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) 
   {
      extract_error("Describe param",dbc, SQL_HANDLE_DBC);  
       
      goto cleanup;
   }

   // Allocate statement handle.
   retcode = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) 
   {
      extract_error("Allocation ... ",stmt, SQL_HANDLE_STMT);  
       
      goto cleanup;
   }

   //tell the driver to work only in sync mode !
   SQLSetStmtOption(dbc, SQL_ASYNC_ENABLE, SQL_ASYNC_ENABLE_OFF);

   if (SQL_SUCCESS !=  SQLExecDirect(stmt,  (SQLCHAR *)
            "IF EXISTS "
            "(SELECT * FROM sysobjects WHERE id = "
            "object_id(N'[dbo].[" TABLE_NAME "]') "
            "AND OBJECTPROPERTY(id, N'IsUserTable') = 1) "
            "DROP TABLE [dbo].[" TABLE_NAME "]; " 
            "CREATE TABLE [dbo].[" TABLE_NAME "] "
            "( name varchar(256), content varbinary(max) NOT NULL ); ",    
            SQL_NTS))
   {
      extract_error("drop + create table ... ",stmt, SQL_HANDLE_STMT);  
       
      goto cleanup;
 
   }
   
   lbytes = (SDWORD) sizeof(binary_data);
   //we are setting the length to be calculated on run time.
   cbTextSize = SQL_LEN_DATA_AT_EXEC(lbytes);

   // Bind the parameter marker.
   
   SQLSMALLINT    binded_column_type,
                  persicion_in_binded_column,
                  is_binded_type_nullable;
   
   SQLUINTEGER   binded_column_size_from_driver = 0;
   
   retcode = SQLPrepare( stmt,
                         (SQLCHAR*)"INSERT INTO " 
                                    TABLE_NAME 
                        " (name, content) VALUES ('file', ?)",SQL_NTS);

#if 0

//for now freetds does not support describe param 
// but on the second it does I must use describe
//      param inorder to get the correct sizes and column types
   retcode = SQLDescribeParam(stmt,
         1,
         &binded_column_type,
         &binded_column_size_from_driver,
         &persicion_in_binded_column,
         &is_binded_type_nullable);

   printf ("Desc info (%d) %d %d %d %d\n",retcode , binded_column_type , 
binded_column_size_from_driver, persicion_in_binded_column, is_binded_type_nullable);

   if (binded_column_type != SQL_LONGVARBINARY) 
   {
        printf("This is strange got %d instead of %d\n" , 
binded_column_type, SQL_LONGVARBINARY);
   }

   if (SQL_SUCCESS != retcode ) 
   {
     extract_error("Describe param",stmt, SQL_HANDLE_STMT);  
         goto cleanup;
   }
#else
    binded_column_size_from_driver = 0;//Don't ask me why freetds\
 fails to work with the 2G size 
#endif

   retcode = SQLBindParameter(stmt, 
                              1, 
                              SQL_PARAM_INPUT,
                              SQL_C_BINARY,
                              SQL_LONGVARBINARY,
                              binded_column_size_from_driver
                                        /*2147483647 vs 32K*/,
                              0,
                              (VOID *) 1/* any value other then null*/,
                              0,
                              &cbTextSize);
    
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
      extract_error("Bind param param",stmt, SQL_HANDLE_STMT);  
      goto cleanup;
   }

   // Execute the command.
   retcode = SQLExecDirectA(
                stmt, 
                (SQLCHAR *)"INSERT INTO " 
                            TABLE_NAME 
                           " (name, content) VALUES ('file', ?)", SQL_NTS);
   
   if ( 
        (retcode != SQL_SUCCESS) 
           &&
        (retcode != SQL_NEED_DATA)
           && 
        (retcode != SQL_SUCCESS_WITH_INFO) )
   {
      extract_error("Insert",stmt, SQL_HANDLE_STMT);  
      goto cleanup;
   }

   // We set up the data len to be computed on executing therefor we must \
         actually send the data.
   // prior to calling put data you must first call to SQLParamData .. \
         why, only the odbc masters know 
   retcode = SQLParamData(stmt, &pParmID);
   printf("SQLParam Data = %d \n",retcode);

   if (SQL_NEED_DATA != retcode)
   {
      extract_error("grrr ... ",stmt , SQL_HANDLE_STMT);
      goto cleanup;
   }

   char * pt_data_be_inserted_into_db = binary_data;
   //we defined that data len will be calculated on executing \
        this is the reason why we got this value
  
   if (retcode == SQL_NEED_DATA) 
   {
      
      while (lbytes > batch_size)
      {

         retcode = SQLPutData(stmt,
                   (SQLCHAR*) pt_data_be_inserted_into_db, batch_size);
         lbytes -= batch_size;
         pt_data_be_inserted_into_db += batch_size;
      }
      // Put final batch.
      retcode = SQLPutData(stmt, pt_data_be_inserted_into_db, lbytes); 
      printf("last put data with %d bytes and exited with %d\n", lbytes,retcode);
   
      if ( 
           (retcode != SQL_SUCCESS)
              && 
           (retcode != SQL_SUCCESS_WITH_INFO) )
      {
         extract_error("Put data for stmt",stmt, SQL_HANDLE_STMT);  
         goto cleanup;
      }
     
   }
  
   // send the data to the db.
   retcode = SQLParamData(stmt, &pParmID);
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) 
   {
      extract_error("Final Param data",stmt, SQL_HANDLE_STMT);  
      goto cleanup;
   }
   
cleanup:
   // Clean up.
   SQLFreeHandle(SQL_HANDLE_STMT, stmt);
   SQLDisconnect(dbc);
   SQLFreeHandle(SQL_HANDLE_DBC, dbc);
   SQLFreeHandle(SQL_HANDLE_ENV, henv);
   return 0;
}

void extract_error(
    char *fn,
    SQLHANDLE handle,
    SQLSMALLINT type)
{
    SQLINTEGER     i = 0;
    SQLINTEGER     native;
    SQLCHAR     state[ 7 ];
    SQLCHAR     text[256];
    SQLSMALLINT     len;
    SQLRETURN     ret;

    fprintf(stderr,
            "\n"
            "The driver reported the following diagnostics whilst running "
            "%s\n\n",
            fn);

    perror("Last os error :");
    do
    {
        ret = SQLGetDiagRec(type, handle, ++i, state, &native, text,
                            sizeof(text), &len );
        if (SQL_SUCCEEDED(ret))
            printf("%s:%ld:%ld:%s\n", state, i, native, text);
    }
    while( ret != SQL_NO_DATA );
    fprintf(stderr, "found %d elements of information\n",(i>0)?i - 1:0);
}

יום רביעי, מרץ 16, 2011

להנדס את החתונה שלך ..

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

החתונה אורגנה באותה הדרך שכותבים תוכנה -

מנסים לכסות כל את כל החריגות ומטפלים בכל חריגה בצורה שהתוכנית תמשיך לרוץ.
היו מספר חריגות פיספסנו אז החלתנו לעלות על הכתב.

התכנון מתחיל בביצוע ניהול סיכונים ובניית פתרונות ראליים עבור כל תרחיש לדוגמה:

תרחיש:
הרבנות תדרוש הוכחת יהדות

פתרון:
הוכחת יהדות מתחילה חצי שנה לפני רישום -
קרה - התהליך לקח כ שלושה חודשים במהלך נאלצתי להמציא את מסמכי סבתה של אימי מתחילת המאה ה20 והוריה (1896).

תרחיש:
בית הדין הרבני לא יתרצה מהמסמכים שדרש להוכחת יהדות.

פתרון:

יש להביא מספר אלבומי תמונות של ארבע חמש דורות אחורה (נדרשתי לעשות זאת).
יש להביא תעודות לידה של כל הילדים במשפחה (נכון הם לא מתחתנים אבל נדרשים).
יש להביא תעודות סיום בית ספר + תיכון + אוניברסיטה של ההורים (הזויי אבל צריך).
יש להביא תעודות מיד ושם.
מידע סרוק לא יוצג (יש להדפיס אותו הרב מסרב לבדוק).
חתימות נוטריון מחוץ לישראל על אמיתות תעודות אינן תקיפות (אבל עדיין שווה להביא את זה)
הרבנות אינה מכירה בחתימה אלקטרונית על מסמכים (PGP).


תרחיש:
מתרגם בית הדין הרבני יעשה צרות

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

תרחיש:
אוטובוס שיוצא מעיר אחרת להביא אנשים מאחר לחופה.

פתרון:
תחשיב שעת ההגעה כשעת קבלת הפנים (לפחות שעה לפני החופה).
ביצוע הנסיעה בכביש 6.
הוספת מקדם בטיחות של שעה בפקקים בכביש 6.
מסירת זמן יצאה לאורחים 25 15 - דקות לפני זמן עצירה של אוטבוס בתחנה (תמיד יהיו מאחרים).
הגדרת אחראי הסעה בכל תחנה.
הגדרת גיבוי לאחראי הסעה
הגדרת גיבוי לגיבוי בכל תחנה.
(באותו היום היה פקק בכביש 6 , עיקוב של 30 דקות ביציאה של אוטובוס מתחנה מסויימת התברברות בכביש ועדיין הגיעו בזמן).

תרחיש:
איפור ותסרוקת לכלה לוקח יותר זמן מהמשוער.

פתרון:
בקשה להכנס ראשונה ב 7 בבוקר לספר.
נבחרים לפחות ארבע אתרי צילום שונים המאפשרים הגעה לאתרי צילום
(זה באמת קרה בחתונה ועדיין היה לנו שלושה מקומות צילום).

תרחיש:
לאחר צילומים הכלה צריכה לעשות תיקון תסרוקת (עיקוב של כ 40 דקות).

פתרון:
חזרה מאתרי הצילום חייבת להיות לפחות שעה ורבע לפני תחילת קבלת פנים.
(התרחש לקחנו בחשבון רק 40 דקות איחרנו ב30 דקות).

תרחיש:
אתר צילום נבחר נסגר בגלל גראדים

פתרון:
לפחות גיבוי אתר צילום אחד בנקודה המרוחקת מהטווח.
(תודה לאל לא קרה).

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

תרחיש:
יש צורך בפינוי אנשים מהחתונה (לא חשים בטוב/ שתו יותר מדי וכן הלאה).

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

תרחיש:
חישוקי שמלת הכלה הוויקטוריאנית נפתחים בזמן צילומים.

פתרון:
החתן דואג לחוט אבטחה ופלייר אבטחות (גם חוט ברזל יספיק)
(לא נלקח בחשבון אילתרנו עם דבק סלוטייפ)

תרחיש:
החתן משמין / מרזה - יוצא מגבולות החליפה.

פתרון:
החתן רוחש חליפה שבועיים לפני.

תרחיש:
דרכי הגעה של קרובים מרוחקים נחסמות (רכבת ישראל מחליטה לבטל קו לדוגמה / תאונות וכו').

פתרון:

אירגון נק' לינה לכל אדם והעברת המידע למגיעים שבמקרה הצורך יש נקודות שינה.
(קרה ).

תרחיש:

מוזמנים שהינם אנשי קבע בטייסות לא יוצאים בגלל העלאת כוננות , תקיפות וכן הלאה.

פתרון:
כל אנשי הצבא ובנות זוגם מוגדרים ברזרבה.
(קרה).

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

פתרון:
למצוא מספר תאולוגי קרוב (לא נלקח בחשבון).

ואת החלקים הגיקים (שירותי IRC , ניהול כתובות , ניהול הודעות) נשאיר לפוסט אחר ...

יום שני, מרץ 14, 2011

ועוד חבר נוסף

ראיתי היום הודעה בוואטסאף על תחליף סקייפ חופשי ומאובטח.

ובאתר הפרוייקט ראיתי את הטקסט הבא :

Our goal is to make GNU Free Call ubiquitous in a manner and level of usability similar to Skype, that is, usable on all platforms, and directly by the general public for all manner of secure communication between known and anonymous parties, but without requiring a central service provider to register with, without using insecure source secret binary protocols that may have back-doors, and without having network control points of any kind that can be exploited or abused by external parties. By doing so as a self organizing meshed calling network, we further eliminate potential service control points such as through explicit routing peers even if networks are isolated in civil emergencies.


אכשיו נשאלת השאלה למה הכוונה בפרוטוקולים בינארים בעלי דלת אחורית ?

אם הכוונה רק לסקייפ ניחא אבל פה מדובר על פתרון SIP שמאפשר ביצוע פעולות peer-to-peer האמת אין פה משהוא מאובטח יותר משימוש במערכות אחרות . עדיין מדובר בעוד מימוש כמו pjsip או osip בעל יכולות הצפנה של השיחה.

(1) למעשה לפי התיאור מדובר במוצר שמבצע את אותה הפעולה שהיינו עושים כשהיינו מבצעים שיחות p2p ע"ג רשת שהתקבלה בעקבות zeroconf ברשת הפנימית או ביצוע שיחות ב kadmilia. קיימים היום מספר פתרונות בנושא (למרות שp2p-sip לא ממש פופלארי) לביצוע שיחות בp2p (דוגמה בשלוף) וגם נושא ההצפנה נלקח בחשבון.
כמובן חשוב לזכור שהנושא לא מוסדר עד הסוף - לא קיים ממש RFC אלא רק drafts .

(2) כבר היום קיימים מוצרים המאפשרים ביצוע שיחות בשימוש ב zrtp (לדוגמה זפון או pjsip) על כן השיחה עצמה מוצפנת , נמשיך הלאה קיימים מספר פתרונות להחביא את השיחה עצמה (הסתרת ה SIP) ואף שרתי שמות.

וזה עוד לפני הנקודה שרשתות p2p-sip בשונה מרשתות sip רגילות בעייתיות בלשון המעטה בחיבור:
בגלל שקיים מנגנון זיהוי שהוא לא מוגדר ברמת הפרוטוקול אלה נבחר בכל מימוש חיבור נק כניסה לשרת הופך את הנושא לקשה , עד בלתי אפשרי, נוסיף את העובדה שמדובר ברשתות נפרדות, קשה עד בלתי אפשרי לבצע ממשק של שיחות שירותים שונים (זוכרים איזה סיוט היה לחבר sip ל xmpp ? ) לכן גם אם המוצר יצליח הוא יחייה על כמות משתמשים מאוד מצומצמת.

אז מה ראינו עד אכשיו :
  1. יש פתרונות p2psip בעולם
  2. יש התייחסות לנושאי הצפנה והזדהות
אז מה באמת חדש בפרוייקט , האם בגלל הצטרפות גנו לנושא ?

זה בשבילי כן חדשות הצטרפות של קבוצה גדולה לתחרות זה תמיד עוזר .
אני מקווה שהפרוייקט יצליח - מדובר באירגון עם כסף וכוח שיכול להחזיק את הפרוייקט ואולי אפילו להתממשק לתוך ed2k (השרת עליה סקייפ חייה).

טוב שיהיה בהצלחה מי ידע אולי יהיה פחות כאב ראש לבצע שיחות p2p ...