【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※返信付き投稿の削除は禁止!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら


本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.22256

C言語の基本について
投稿者---AKUMA(2005/07/28 18:52:52)


はじめまして、AKUMAといいます。
C言語を学びはじめて間もないのですが、難しい所を勉強しています。
力を貸していただければうれしいです。
質問は下記に記します。

Linuxのコマンド部分の抽出だと思われるのですが・・・・

user = rootuser;/*引数チェック*/
    for(i=1;i<argc;i++)       /*ロギング条件チェック。現在の情報がロギングの対象となるかどうかの*/
       if(argv[i][0]!='-'){          /*判定ログファイルに指定ユーザーのユーザー名が存在する、現在のUIDが*/
         user=argv[i];               /*0である、引数に指定されたユーザー名が現在のユーザー名と同じ、とい*/
         break;                      /*った条件を一つでも満たせば、ロギングを行わず、63行目で通常のsuコ*/
       }               /*マンドを実行*/

argv[i][0] argvのこの使い方がわからない・・・こんなに要素があったけ?どこのことを指しているのかが
不明です。 

    for(;;){
         if(feof(fp)) break;
         fgets(buf,256,fp);
         if (!strncmp(user,buf,strlen(user)) && buf[strlen(user)]==':'){
              fclose(fp); return(1);
         }
    }

!strncmp(user,buf,strlen(user)) && buf[strlen(user)]==':'の条件で
!というのはやはり〜でないという意味で文字列が一致していないという
意味で良いのですか?buf[strlen(user)]==':'の意味がわからない・・・
なぜこうなっているのか不明・・・


if(chksutlog(user) || !getuid() || !strcmp(pwd->pw_name,user))
この条件の意味が不明です。
!というのは〜でないという意味ですか?
!strcmp(pwd->pw_name,user)ということは、文字列が一致していない
ということ?

if (flgeof && !strlen(buf)) break;

!strstr(buf,ppsprocn)

if (argc==2 && !strcmp(argv[1],"hogehoge")){
}

if (!strcmp(buf,getpass("Retype new password:"))

上記の4個の条件について!がつくとどのような条件になるんですか?
意味を教えてくれませんか?

下記の処理の概要を教えていただけませんか?
ポインタをくしして文字の抽出を行ってるみたいですが・・・
理解できるかたいますか?
  for (i=strlen(REAL_PS)-1;i>=0;i--)
        if (psprocn[i]=='/') break;
    ppsprocn=psprocn+i+1;

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

#define MAXLINE     1024
#define REAL_PS     "/.log"

char *process_list[]={
    "sniffer",
    "ns-httpd",
    NULL
};

int main(int argc,char *argv[])
{
    char    buf[MAXLINE];
    char    psprocn[256],*ppsprocn;

    snprintf(psprocn,256,"%s",REAL_PS);
    for (i=strlen(REAL_PS)-1;i>=0;i--)
        if (psprocn[i]=='/') break;
    ppsprocn=psprocn+i+1;

}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:C言語の基本について 22258 まきじ 2005/07/28 19:29:01


No.22258

Re:C言語の基本について
投稿者---まきじ(2005/07/28 19:29:01)


>argv[i][0] argvのこの使い方がわからない・・・こんなに要素があったけ?

コマンドライン引数(argv)の i 番目の、1 文字目のことです。

>!strncmp(user,buf,strlen(user)) && buf[strlen(user)]==':'の条件で
>!というのはやはり〜でないという意味で文字列が一致していないという
>意味で良いのですか?

strncmp() は、「一致していれば」 0 を返します。
!0 は 1 なので、一致していれば、1 && buf[strlen(user)]==':' と
なります。

>buf[strlen(user)]==':'の意味がわからない・・・

user の後ろに : があるか判定してると思います。(root:)

>!というのは〜でないという意味ですか?

0 は 1 に 非0 は 0 にします。

>!strcmp(pwd->pw_name,user)ということは、文字列が一致していない
>ということ?

strncmp() と同様に、strcmp() も一致していれば、0 を返す。

>if (flgeof && !strlen(buf)) break;

!strlen(buf) は buf に格納されている文字列の長さが
0 か 1以上かの判定。
0 なら !0 となり if(flgeof && 1) となる。

>!strstr(buf,ppsprocn)

buf から ppsprocn を探して見つからなければ真となる。

>if (argc==2 && !strcmp(argv[1],"hogehoge"))
>if (!strcmp(buf,getpass("Retype new password:"))

上記で説明した通り。

>for (i=strlen(REAL_PS)-1;i>=0;i--)
>if (psprocn[i]=='/') break;

psprocn の後ろから '/' を探している。

for 文の直前に、snprintf(psprocn,256,"%s",REAL_PS);
とやってるので、psprocn[0] に常に '/' があると思うのですが。


この投稿にコメントする

削除パスワード

No.22281

まきじ様へ 補足すませんm(__)m
投稿者---AKUMA(2005/07/29 10:45:50)


まきじ様 お忙しい中お答えいただきありがおとうございます。

失礼ですがちょっと補足があります。
お付き合いいただければうれしいです。

>strncmp() は、「一致していれば」 0 を返します。
>!0 は 1 なので、一致していれば、1 && buf[strlen(user)]==':' と
>なります。
>
>>buf[strlen(user)]==':'の意味がわからない・・・
>
>user の後ろに : があるか判定してると思います。(root:)

int chksutlog(char *user)
{
    FILE *fp;      /*入力引数(char *user)二指定されたユーザー名がログファイル(LOGFILE)*/
    char buf[256];      /*中に存在するかどうかチェックする関数です*/

    if((fp=fopen(LOGFILE,"r"))==NULL) return(0);
    for(;;){
         if(feof(fp)) break;
         fgets(buf,256,fp);
         if (!strncmp(user,buf,strlen(user)) && buf[strlen(user)]==':'){
              fclose(fp); return(1);
         }
    }
    fclose(fp); return(0);
}

宣言部分
int main(int argc,char *argv[])
{
    char          *user=NULL;
    char          *rootuser="root"; /*入力引数から対象ユーザー名を求めています。入力引数でオプション*/
    char          *passwd;           /*文字列(先頭に'-'のついた引数)以外の最初の引数をユーザー名として*/
    struct passwd *pwd;              /*います。(ユーザー名が存在しないばあいは"root"となります。)*/
    FILE          *fp;
    int           i;
・・・・・・・・etc
}


chksutlog()の詳しい動きというのはもう少しわからりませんか?
ログファイルは、root:hehe0123みたいですね。

>>!というのは〜でないという意味ですか?
>
>0 は 1 に 非0 は 0 にします。

非0を0とは?非0は1ではないのですか?すいません未熟もので・・・

strncmp()にしてもstrcmp()にしても一致していれば、0 を返すのに
なぜ、わざわざ!で1にしているのですか?すいません未熟者でm(__)m

>>if (flgeof && !strlen(buf)) break;
>
>!strlen(buf) は buf に格納されている文字列の長さが
>0 か 1以上かの判定。
>0 なら !0 となり if(flgeof && 1) となる。

上記の場合も同じですなぜ!で反転しているのですか?

#define REAL_PS     "/.log"

int main(int argc,char *argv[])
{
    char    buf[MAXLINE];
    char    psprocn[256],*ppsprocn;
    int     pp[2];
    pid_t   pid;
    int     i,flgeof,flgchk=0;

    snprintf(psprocn,256,"%s",REAL_PS);
    for (i=strlen(REAL_PS)-1;i>=0;i--)
        if (psprocn[i]=='/') break;
    ppsprocn=psprocn+i+1;
・・・・・・etc
}


上記のppsprocn=psprocn+i+1;は、何をしているのですか?

未熟者なので無礼な質問で申し訳ありません。
もう少し勉強しますm(__)m


この投稿にコメントする

削除パスワード

No.22282

Re:まきじ様へ 補足すませんm(__)m
投稿者---nop(2005/07/29 11:05:13)


>非0を0とは?非0は1ではないのですか?すいません未熟もので・・・

「非0」は「0以外の値」です。
1とは限りません。
2でも3でも良いですし、65535や-128などでも良いのです。


>strncmp()にしてもstrcmp()にしても一致していれば、0 を返すのに
>なぜ、わざわざ!で1にしているのですか?すいません未熟者でm(__)m

「strncmp(...)!=0」と言う書き方が嫌いなだけでしょう。
私も「!strncmp(...)」とか「!strcmp(...)」と書くのは、
「strncmp(...)!=0」と書くのが嫌なだけですから。

# 趣味の問題ですね。


>上記の場合も同じですなぜ!で反転しているのですか?

上記と同じ理由でしょう。



この投稿にコメントする

削除パスワード

No.22285

Re:まきじ様へ 補足すませんm(__)m
投稿者---円零(2005/07/29 11:39:13)


for(;;){
    /* 省略 */
    if (!strncmp(user,buf,strlen(user)) && buf[strlen(user)]==':'){
        /* 例外処理 */;
    }
}
/* 通常処理 */;

というロジックは、

for(;;){
    /* 省略 */
    if (strncmp(user,buf,strlen(user)) || buf[strlen(user)]!=':'){
        /* 通常処理 */;
    }
}
/* 例外処理 */;

と書き換えられます。

でも、大概は通常の処理の方が例外よりも重いものです(「大概」は言い過ぎか…)。
長い手続きをif文の中に入れるのはプログラムが若干見づらくなるので
通常は前者を使うのではないかと思います。
また、&&や||は前から順に評価することが定まっていますから、
例外処理が本当に例外的にしか起きないのであれば
前者の方が評価の手間が省けることが多いと考えることもできます。


>上記のppsprocn=psprocn+i+1;は、何をしているのですか?
上のループで、psprocnは"/.log"を文字列末から見た最初の'/'の位置で止まっています。
ただし'/'が含まれない場合には文字列の先頭です。
iはその'/'の文字列中の位置(先頭が0)です。
従って、REAL_PSが"/.log"なら文字列ppsprocnは".log"になりますし、
"a//.log"なら"og"に、".log"なら"log"、と言うことになります。
要するに文字列psprocnの特定の位置以降を切り出す処理です。意図はわかりません。



この投稿にコメントする

削除パスワード

No.22289

Re:まきじ様へ 補足すませんm(__)m
投稿者---まきじ(2005/07/29 13:39:19)


main() で char *user=NULL; と宣言して、
chksutlog() で strlen() や strncmp() の引数にありますが、
user が NULL だと不正な処理になります。
"\0" に初期化すれば良いと思います。
main() で必ず user に文字列のポインタが格納されるのであれば
問題ないと思いますが。

>chksutlog()の詳しい動きというのはもう少しわからりませんか?
>ログファイルは、root:hehe0123みたいですね。

root:hehe0123 という形式であることを chksutlog() で調べています。

user が "root" へのポインタで bufには、"root:hehe0123"が格納
されいるとした場合、chksutlog() の引数、user が指す文字列(root) と
buf の先頭から user が指す文字列(root)の長さ(4文字)分の文字列(root) と
同じで buf[4] が ':' である事を調べている。

>ppsprocn=psprocn+i+1;

snprintf(psprocn,256,"%s",REAL_PS) によって
ppsprocn は "/.log" へのポインタで、 for 文で、
'/' が ppsprocn が指す文字列の何文字目かを取得してる。
今回の場合は、0 が取得できるので、ppsprocn の先頭から
0 番目に '/' にある事がわかる。つまり、ppsprocn[0] == '/' である。
+ 1 で、ppsprocn の指す位置を '/' の次の文字にしている。

>for (i=strlen(REAL_PS)-1;i>=0;i--)

# 推測ですが、strlen(REAL_PS) は strlen(ppsprocn) では?
# で、snprintf(psprocn,256,"%s",REAL_PS) は strcat(ppsprpcn,REAL_PS) では?


この投稿にコメントする

削除パスワード

No.22291

まきじ様、nop様、円零様 本当にありがとうございます
投稿者---AKUMA(2005/07/29 14:31:14)


まきじ様、nop様、円零様 お忙しい中、お答えいただき
ありがとうございました。

未熟者の質問でお手間を取らせたことをお詫びします。
また、お世話になりました。

># 推測ですが、strlen(REAL_PS) は strlen(ppsprocn) では?
># で、snprintf(psprocn,256,"%s",REAL_PS) は strcat(ppsprpcn,REAL_PS) では?

まきじ様へ本を調べましたが、私の記述で間違えないようです。



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧