2018年1月10日 星期三

linux kernel printk

https://www.kernel.org/doc/Documentation/printk-formats.txt

16進位e自動顯示0x
pintk( " %#x " ,hex);

常用
int %d or %x
unsigned int %u or %x
long %ld or %lx
unsigned long %lu or %lx
long long %lld or %llx
unsigned long long %llu or %llx
size_t %zu or %zx
ssize_t %zd or %zx
s32 %d or %x
u32 %u or %x
s64 %lld or %llx
u64 %llu or %llx


MAC
%pM 00:01:02:03:04:05
%pMF 00-01-02-03-04-05

IPv4
%pI4 1.2.3.4
%pi4 001.002.003.004
%p[Ii]4[hnbl]
The additional ``h``, ``n``, ``b``, and ``l`` specifiers are used to specify
host, network, big or little endian order addresses respectively. Where
no specifier is provided the default network/big endian order is used.

IPv6
%pI6 0001:0002:0003:0004:0005:0006:0007:0008
%pi6 00010002000300040005000600070008
%pI6c 1:2:3:4:5:6:7:8



2017年9月5日 星期二

IGMP multicast with vlc

windows server
1.Open cmd as administrator
2.route delete 224.0.0.0 mask 240.0.0.0
3.route add 224.0.0.0 mask 240.0.0.0 <IP of NIC>

VLC version 2.26

使用UDP 打流

2017年3月2日 星期四

C 語言中的函數指標

ref.http://ccckmit.wikidot.com/cp:main

C 語言中的函數指標

#include <stdio.h>
int add(int a, int b)
{
return a+b;
}
int mult(int a, int b)
{
return a*b;
}
int main()
{
int (*op)(int a, int b);
op = add;
printf("op(3,5)=%d\n", op(3,5));
op = mult;
printf("op(3,5)=%d\n", op(3,5));
}



函數指標型態 -- (function pointer type) 用typedef 將函數指標宣告成一種型態

#include <stdio.h>
typedef int(*OP)(int,int);
int add(int a, int b) 
{
return a+b;
}
int mult(int a, int b) 
{
return a*b;
}
int main() 
{
OP op = add;
printf("op(3,5)=%d\n", op(3,5));
op = mult;
printf("op(3,5)=%d\n", op(3,5));
}



變動參數


#include <stdio.h>
#include <stdarg.h>
void printList(int head, ... ) 
{
va_list va;
va_start(va, head);
int i;
for(i=head ; i != -1; i=va_arg(va,int)) 
{
printf("%d ", i);
}
va_end(va);
}

int main( void ) 
{
printList(3, 7, 2, 5, 4, -1);
}

變動參數2

#include <stdio.h>
int debug(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
return vprintf(fmt, args);
}
int main() 
{
debug("pi=%6.2f\n", 3.14159);
}



陳鍾誠 (2010年09月01日),(網頁標題) C 語言結構中的位元欄位,(網站標題) 陳鍾誠的網站,取自 http://ccckmit.wikidot.com/cp:structbits ,網頁修改第 5 版。


2017年2月28日 星期二

printf sprintf snprintf asprintf / fgets gets scanf sscanf 表示式

http://edisonx.pixnet.net/blog/post/35305668-%5Bc%5D-printf-%E5%BC%95%E6%95%B8%E8%AA%AA%E6%98%8E




fgetc,fputc,fgets,fputs,fscanf,fprintf,fread,fwrite


#include <stdio.h>

int main()
{
   printf ("Characters: %c %c \n", 'a', 65);
   printf ("Decimals: %d %ld\n", 1977, 650000L);
   printf ("Preceding with blanks: %10d \n", 1977);
   printf ("Preceding with zeros: %010d \n", 1977);
   printf ("Some different radixes: %d %x %o %#x %#o \n", 100, 100, 100, 100, 100);
   printf ("floats: %4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416);
   printf ("Width trick: %*d \n", 5, 10);
   printf ("%s \n", "A string");
   return 0;
}

Characters: a A
Decimals: 1977 650000
Preceding with blanks:       1977
Preceding with zeros: 0000001977
Some different radixes: 100 64 144 0x64 0144
floats: 3.14 +3e+000 3.141600E+000
Width trick:    10
A string



http://ccckmit.wikidot.com/cp:sscanf
#include <stdio.h>

int main() {
  char name[20], tel[50], field[20], areaCode[20], code[20];
  int age;
  sscanf("name:john age:40 tel:082-313530", "%s", name);
  printf("%s\n", name);
  sscanf("name:john age:40 tel:082-313530", "%8s", name);
  printf("%s\n", name);
  sscanf("name:john age:40 tel:082-313530", "%[^:]", name);
  printf("%s\n", name);
  sscanf("name:john age:40 tel:082-313530", "%[^:]:%s", field, name);
  printf("%s %s\n", field, name);
  sscanf("name:john age:40 tel:082-313530", "name:%s age:%d tel:%s", name, &age, tel);
  printf("%s %d %s\n", name, age, tel);
  sscanf("name:john age:40 tel:082-313530", "%*[^:]:%s %*[^:]:%d %*[^:]:%s", name, &age, tel);
  printf("%s %d %s\n", name, age, tel);

  char protocol[10], site[50], path[50];
  sscanf("http://ccckmit.wikidot.com/cp/list/hello.txt", 
         "%[^:]:%*2[/]%[^/]/%[a-zA-Z0-9._/-]", 
         protocol, site, path);
  printf("protocol=%s site=%s path=%s\n", protocol, site, path);
  return 1;
}
其編譯執行結果如下所示。
D:\oc>gcc sscanf.c -o sscanf

D:\oc>sscanf
name:john
name:joh
name
name john
john 40 082-313530
john 40 082-313530
protocol=http site=ccckmit.wikidot.com path=cp/list/hello.txt


%s 可以用%[] 來表示的更精確
^ 表示非的意思  
讀到換行符號即停止(換行符並不會從緩衝區讀出)
ex. %[^\n] 
*代表忽略相關病讀出緩衝區


用 snprintf / asprintf 取代不安全的 sprintf




*scanf/gets/fgets

scanf : 不安全  若buff 比讀入的還小的話會造成溢位
https://sites.google.com/site/9braised/fan-si/c1
http://squall.cs.ntou.edu.tw/cprog/practices/scanfCommonTraps.pdf

特性:
接下來請注意需要完全了解 scanf() 每一個控制命令 scanf() 所做的動作, 例
*如 %s是
"跳過0或多個 white space, 由鍵盤緩衝區裡讀取連續不是 whitespace 的字元"
, 所謂 white space 包括 空格, '\t',和 '\n' 三個字元
*又例如 %c是
"不跳過任何字元, 直接由鍵盤緩衝區裡讀取單一一個字元"
* %d 是
"跳過所有 white space, 由鍵盤緩衝區裡讀取連續 0~9 之間的十進位數字, 轉換為二進位"
如果除了 white space 之外只看到不是 0~9 的字元,scanf("%d",&x) 回傳 0
(注意是回傳 0 代表這個命令沒有成功, x 的數值不變)


gets : 同樣不安全  會一直讀到'\n' 為止且將'\n'自動轉為'\0'丟進buff
       ,若buff 不夠大,和scanf 有同樣的問題


fgets(str, sizeof(str), stdin);
較安全,因為有限制大小len,但是很是有許多不足的地方
1.當資料不足時fgets 會讀入換行資訊
2.當資料被len限制而截斷時,stdin 會留下剩下殘存的資訊導致下次讀入錯誤


2017年1月25日 星期三

linux 資料流重導向 (redirecte) stderr stdout


ref.鳥哥
ref.http://dywang.csie.cyut.edu.tw/dywang/linuxProgram/node20.html


資料流重導向

標準輸入(stdin) :代碼為 0 ,使用 < 或 << ;
標準輸出(stdout):代碼為 1 ,使用 > 或 >> ;
標準錯誤輸出(stderr):代碼為 2 ,使用 2> 或 2>> ;

>> 為 append
>   為覆寫


1> :是將正確的資料輸出到指定的地方去
2> :是將錯誤的資料輸出到指定的地方去
若只下> 則預設等義>1


將資料輸出到不同的地方去呢?可以這麼寫:
find /home -name testing > list_right 2> list_error


將錯誤的資訊丟掉!
 find /home -name testing > list_right 2> /dev/null


 find /home -name testing > list 2> list <==錯誤寫法

find /home -name testing > list 2>&1 <==正確寫法
or
find /var -name run &>file
請特別留意這一點呢!同時寫入同一個檔案需要使用 2>&1 才對呦!
(這邊我的理解為 把 stderr導向stdout 的address   2>&1) 如此一來 stderr 就變為stdout了


方便的make linux
 alias mkl='make linux vmimg 2>&1 | grep -i "error:\|correct"'




連續命令

指令間以分號( ; )隔開:連續執行指令。
[root@linux ~]# sync; sync; shutdown -h now

指令間以 && 隔開:前面指令執行結果正確,就接著執行後續的指令,否則就略過。
[root@linux ~]# ls /tmp && touch /tmp/testingagin
 ## 目錄/tmp存在,所以/tmp/testingagin會被建立。

[root@linux ~]# ls /csie && touch /csie/test
## 目錄/csie不存在,所以touch /csie/test不會被執行。

指令間以 || 隔開:前一個指令有錯誤時,後面的指令才被執行。
[root@linux ~]# ls /tmp/csieing || touch /tmp/csieing


2016年5月29日 星期日

linux 加入PATH 環境變數

http://linux.vbird.org/linux_basic/0320bash.php#settings

http://www.linuxfromscratch.org/blfs/view/svn/postlfs/profile.html


fast.

修改 ~/.bashrc 或 ~/.profile
  1. 若該變數為擴增變數內容時,則可用 "$變數名稱" 或 ${變數} 累加內容,如下所示:
    『PATH="$PATH":/home/bin』或『PATH=${PATH}:/home/bin』
  2. 若該變數需要在其他子程序執行,則需要以 export 來使變數變成環境變數
    『export PATH』

ex.

vim ~/.bashrc
or
vim ~/.profile

加入以下

# User specific environment and startup programs
PATH=${PATH}:/opt/bin
export PATH


2016年5月26日 星期四

NAS learn



開啟ssh PubkeyAuthentication 服務
ref.https://www.chainsawonatireswing.com/2012/01/15/ssh-into-your-synology-diskstation-with-ssh-keys//?from=@


To start the process, you need to edit the SSH daemon’s config file to allow access via keys.

Edit/etc/ssh/sshd_config using vim & change these lines:

#RSAAuthentication yes 
#PubkeyAuthentication yes 
#AuthorizedKeysFile .ssh/authorized_keys

To this:

RSAAuthentication yes 
PubkeyAuthentication yes 
AuthorizedKeysFile .ssh/authorized_keys


Now get your permissions set correctly on that directory & file:> chmod 700 .ssh

> chmod 600 .ssh/authorized_keys

> chmod 700 .ssh/

再來是client 端 ,基本的概念就是使用private key 去開在遠端server public key

生成privatekey 和publickey
#ssh-keygen 

copy 到遠端的~/.ssh下
#scp id_rsa.pub username@serverip:~/.ssh/
登入遠端server
ssh username@serverip

將public key 加入.ssh/authorized_keys  (我的cat 曾經動過手腳 alias 成 cat -n 害我卡了一整個晚上  哭哭)
cat .ssh/id_rsa.pub >> .ssh/authorized_keys 

這樣子就可以 key 認證登入, 不需輸入密碼.


重開遠端server ssh
Restarted sshd via synoservicectl --restart sshd and by restarting whole NAS.
or
rebooot

2016年5月24日 星期二

linux server 記事 ubuntu 16.04LTS

家裡退休的筆電閒了下了,因此打算架個 linux server 來玩玩
在這邊紀錄一下架設日誌,過程,供日後參考。

安裝版本為 ubuntu 16.04 LTS desktop x64 english



*更新軟體
apt-get update
apt-get upgrade

*備份
rsync + ssh + crontab

1.先處理免密碼登入的 RSA key

2.編輯vim backup_script.ssh 內容只有一行
rsync -av /* username@serverip::NetBackup/ngulinux/ --rsh='ssh -i userPrivateKey' --exclude={/dev/*,/home/username/.cache/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found}

不知道為何我上面的指令可以直接 單run script 執行沒問題,但是加到crontab時 ㄍ--exclude 指令沒起到作用,因此只好把此指令拔掉將除外的檔案塞到額外的檔案,作法大概是
rsync -av /* username@serverip::NetBackup/ngulinux/ --exclude-from='/root/rsync_bk/excludeList'  --rsh='ssh -i userPrivateKey' -

然後建立一個檔案叫 excludeList 在路徑上
檔案的寫法大概是
/dev/
/proc/
/sys/
/tmp/
/run/
/mnt/
/media/
/lost+foun/
.cache/
google-chrome/
/var/tmp/
/var/log/

大概說明一下
/dev/    代表略過此目錄(連目錄都不產生)
/dev/*  複製此目錄但是略過此目錄下所有檔案
dev/     所有檔案或目錄的名稱的任意位置包含 dev 的都略過

3.將backup_script.ssh 加進crontab
vim /etc/crontab

* * * * * root /bin/sh /cronfiles/rsync.sh
(分 時 日月 周) (執行者) (執行shell) (script)

10 5    * * *   root    /root/rsync_bk/rsync.sh >> /var/log/rsync.log 2>&1

收割
#/etc/init.d/cron restart


*遠端桌面
1.anydesk  http://anydesk.com/remote-desktop
2.teamviewer  https://www.teamviewer.com/
3.VNC xrdp
ref.http://programingman.blogspot.tw/search/label/raspberry

*文字介面開機

vim /etc/default/grub

修改成以下參數

#GRUB_HIDDEN_TIMEOUT=0
#GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=3
GRUB_CMDLINE_LINUX_DEFAULT="text"
GRUB_CMDLINE_LINUX="text"
GRUB_TERMINAL=console

開啟多人模式
sudo systemctl enable multi-user.target --force 
sudo systemctl set-default multi-user.target
更新
update-grub

若要開啟x-window 不知道為何我的 startx 無效
需要
service lightdm restart
or 
 /etc/init.d/lightdm restart
才可以再開啟x-window

到此告一段落,我做出的效果差不多就是開機為tty1 文字模式
遠端可以隨時xrdp 回來x-window (使用Windows),當server 有問題時也可以使用x-window 來控制

在這邊不得不推崇一下 Teamviewer,發現使用teamviewer 設定好後不用登入到 x-window 畫面
在TTY1 純文字下就可以連進來下 command 不知道怎麼做的,有點厲害
若在TTY1 下使用 service lightdm restart ,畫面也會自動轉為x-window , 是個蠻棒的環境

所以在我的環境下
1.可以使用xrdp 直接遠端進我的 Sever 桌面 (不需要 service lightdm restart)
2.可以使用teamviewer 進來下 service lightdm restart 後直接轉成我的桌面
3.SSH 近來我的server

完成,媽呀 因為我的是筆電,每次重開機時只要系統偵測到是蓋著的就自動休眠

# 按下電源 預設行為為關機
HandlePowerKey=poweroff
 # 按下暫停
 HandleSuspendKey=suspend 
# 按下休眠 
HandleHibernateKey=hibernate
 # 闔上螢幕
# HandleLidSwitch=suspend
HandleLidSwitch=ignore

vim /etc/systemd/logind.conf

*必備軟體
sudo apt-get install vim
sudo apt-get install tmux

chewing
upnpc
openssh-server

*wake-on-Lan 網路喚醒

#ethtool interfaceName
查看 這兩個參數
Supports Wake-on: pg
Wake-on: d

d為disable 的意思  g為magic packet 可以喚醒的意思

使用指令將 Wake-on 改為 g

#ethtool -s eth0 wol g

之後就可以關機試試看效果了
另一台電腦使用
wakelan or wakeonlan 之類的指令試試看可不可以喚醒

wakeonlan YOUR_TARGET_MAC -b 192.168.0.255

-b 為指定brocast packet  因為 中間的router or switch 若因為arp timeout 有可能default 的行為不是flooding 而是drop 使用brocast packet 是比較保險的做法

其中ethtool -s eth0 wol g 只有一次性,因此需要用你所想的道的方式設定他always on
ex.加入排程 crontab

way2. 使用nmcli 指令設定
# nmcli con show
NAME    UUID                                  TYPE            DEVICE
enp9s0  e33fd8e4-bf42-4652-8a85-55e4ebc49d24  802-3-ethernet  enp9s0

查看wol 是否有開啟
# nmcli c show "enp9s0" | grep 802-3-ethernet.wake-on-lan
802-3-ethernet.wake-on-lan:             80 (broadcast, magic)
802-3-ethernet.wake-on-lan-password:    --

修改成接收broadcast and magic paacket 
nmcli c modify "enp9s0" 802-3-ethernet.wake-on-lan magic,broadcast

(後記:在我的環境兩種方式都設定過了還是不work ,發包的magic packet 沒有錯誤,另一台電腦可以順立wol,因此猜測應該是硬體支援的問題,
先暫時放棄此功能,原本想法是有要連進來再利用gateway 將server 喚醒避免不必要的耗電,畢竟當server 是不太會關機的)


*sudo 免密碼

因為常常在 sudo 我的密碼又很大一串,所以索性用個免密碼sudo 這樣就不用先轉成 root 在做事

修改方式大概為

(舊版方式)
在username最後的一個ALL 前加入 NOPASSWD
username ALL=(ALL) NOPASSWD: ALL
username ALL=(ALL:ALL) NOPASSWD: ALL

上面兩種用法就看你的系統是用哪種語法跟著原本的方式寫就是了

注意若此檔修改錯誤會造成無法使用 sudo 指令,因此語法要注意一下
最好的方式是使用visudo 指令修改,會幫你檢查與法有無錯誤

更新 新版方式更安全些寫在/etc/sudoers.d

vi /etc/sudoers.d/nopasswd4sudo
输入 
yourusername ALL=(ALL) NOPASSWD : ALL
ESC :wq!




*SAMBA 參考 (點我)

但是瑞凡  我失敗了,不知道為何 在我的Raspberry mate 15.04 是成功的 在16.04失敗,也不知從何Debug 起 ,先擱著好了。

# Un-comment the following (and tweak the other settings below to suit)
# to enable the default home directory shares. This will share each
# user's home directory as \\server\username
[homes]
comment = Home Directories
browseable = yes

結果是這段的 [homes] 沒有打開,ㄍㄋㄋ  搞了我一個晚上















2016年3月30日 星期三

Synology 6.0 root passwd

DSM 在6.0有做一些修正導致無法使用root 登入(安全性考量 default ban 掉root),或者是拿不到權限

比較簡單的作法是使用管理者帳號登入然後下 (這邊加進sudo 的功能)
sudo -i
即可變成root 登入

但是還是無法直接使用root 登入,若sudo 失效系統就GG

所以還是有其他方法改成直接使用root登入如下


After getting the DSM 6.0 upgrade, I’ve become unable to login as root using SSH, even though I’ve been able to do it before the upgrade (DSM 5.5 or something like that).
The solution:
1. SSH to machine as admin user.
2. Enter command “sudo su” and providing admin password.
3. Enter command “synouser --setpw root yourPasswd “.
Now I’m able to logon as root using SSH again, and I didn’t have to mess with telnet.

這是更新的經驗是,以後synology 不要亂進大版(我從DSM5.2 -> DSM6.0),否環境可能會被改到,還要再弄一次。

/etc 下的chmod 權限不要亂改,我為了讓權限打開 修改此檔暫時將 /etc/sudoers權限改為chmod 777 ,然後就發生悲劇了,使用sudo 指令時都出現

sudo: /etc/sudoers is world writable
sudo: no valid sudoers sources found, quitting
sudo: unable to initialize policy plugin

意思是任何人都可以修改此檔,系統認為此檔無效,因此sudo 不吃此檔案
想改回來需要sudo chmod 但是又先執行了sudo 引此就卡死了,然後系統又不能使用使用root登入將此檔的權限改回來,整個系統差點GG

還好在/opt/bin/ 底下我也有安裝sudo 使用此執行的改回來就正常了。