« 岩屋ダム | トップページ | 修理から帰ってきたiMac »

2011/07/22

MacでFirewall越しに時刻をあわせる

 Macのシステム環境設定→日付と時刻に、「日付と時刻を自動的に設定」機能がありますが、ファイヤーウォールでNTPが塞がれていると自動的に設定されません。
 そこで、思いつきで作ってみました。とりあえずコマンドラインで動くアプリケーションで、Launchdで呼び出すようにしました。
 内容は簡単で、NICTが提供している時刻を読み込み、Macの時刻をその時刻に合わせます。エラー処理が全くないので、実運用時はエラー処理を追加してください。


JSTAccess.m

#include <CoreServices/CoreServices.h>
#include <Cocoa/Cocoa.h>
#include <sys/time.h>

int main (int argc, const char * argv[]) {
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

 static const long kNtpToPosix = 2208988800;

 // NTPにアクセスする
 NSURL *url;
 NSMutableURLRequest *request;
 NSData *data;
 NSURLResponse *response;
 NSError *error;
 NSString *htmlString;
 NSDate *startDate;
 NSTimeInterval interval;

 url = [NSURL URLWithString:@"http://ntp-a1.nict.go.jp/cgi-bin/ntp"];
 request = [NSMutableURLRequest requestWithURL:url];
 startDate = [NSDate date];
 data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
 interval = [startDate timeIntervalSinceNow];
 htmlString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

 // htmlDataからNTP時刻を抽出する
 NSRange startRange;
 NSRange endRange;
 NSRange ntpRange;
 int location;
 int length;
 NSString *ntpString;

 startRange = [htmlString rangeOfString:@""];
 endRange = [htmlString rangeOfString:@""];
 location = startRange.location + startRange.length + 1;
 length = endRange.location - startRange.location - startRange.length - 2;
 ntpRange = NSMakeRange(location, length);
 ntpString = [htmlString substringWithRange:ntpRange];

 // NTP時刻からPOSIX時刻へ変更し、書き込み
 double posixTime;
 time_t tv_sec;
 suseconds_t suseconds;

 posixTime = [ntpString doubleValue] - kNtpToPosix - interval / 2;
 tv_sec = (time_t)posixTime;
 suseconds = (suseconds_t)((posixTime - (double)tv_sec) * 1000.0);
 struct timeval tp = {tv_sec, suseconds};
 settimeofday(&tp, NULL);
 [htmlString release];

 NSLog(@"%@", [NSDate dateWithTimeIntervalSince1970:posixTime]);
 [pool drain];

 return 0;
}

 コンパイルして完成した実行ファイルをアプリケーションフォルダに移動します。そして、Launchdを作ります。ここでは、毎時0分にアプリケーションを呼び出すようにしています。


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
 <dict>
  <key>Label</key>
  <string>private.JSTAccess</string>
  <key>ProgramArguments</key>
  <array>
   <string>/Applications/JSTAccess</string>
  </array>
  <key>StartCalendarInterval</key>
  <dict>
   <key>Minute</key>
   <integer>0</integer>
  </dict>
 </dict>
</plist>

 ひとまず覚え書き程度に。エラー処理などしっかり加えたらバイナリを公開する予定です。


|

« 岩屋ダム | トップページ | 修理から帰ってきたiMac »

パソコン・インターネット」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/3290/52251544

この記事へのトラックバック一覧です: MacでFirewall越しに時刻をあわせる:

« 岩屋ダム | トップページ | 修理から帰ってきたiMac »