00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00040
00041
00042 #include "midas.h"
00043 #include "msystem.h"
00044
00045 #ifdef OS_UNIX
00046 #include <sys/mount.h>
00047 #endif
00048
00049 static INT ss_in_async_routine_flag = 0;
00050 #ifdef LOCAL_ROUTINES
00051 #include <signal.h>
00052
00053
00054
00055
00056
00057 BOOL disable_shm_write = FALSE;
00058
00059
00060 INT ss_set_async_flag(INT flag)
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 {
00081 INT old_flag;
00082
00083 old_flag = ss_in_async_routine_flag;
00084 ss_in_async_routine_flag = flag;
00085 return old_flag;
00086 }
00087
00088
00089 INT ss_shm_open(char *name, INT size, void **adr, HNDLE * handle)
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 {
00114 INT status;
00115 char mem_name[256], file_name[256], path[256];
00116
00117
00118 sprintf(mem_name, "SM_%s", name);
00119
00120
00121 cm_get_path(path);
00122 if (path[0] == 0) {
00123 getcwd(path, 256);
00124 #if defined(OS_VMS)
00125 #elif defined(OS_UNIX)
00126 strcat(path, "/");
00127 #elif defined(OS_WINNT)
00128 strcat(path, "\\");
00129 #endif
00130 }
00131
00132 strcpy(file_name, path);
00133 #if defined (OS_UNIX)
00134 strcat(file_name, ".");
00135 #endif
00136 strcat(file_name, name);
00137 strcat(file_name, ".SHM");
00138
00139 #ifdef OS_WINNT
00140
00141 status = SS_SUCCESS;
00142
00143 {
00144 HANDLE hFile, hMap;
00145 char str[256], *p;
00146 DWORD file_size;
00147
00148
00149
00150
00151
00152 strcpy(str, path);
00153
00154
00155 while (strpbrk(str, "\\: "))
00156 *strpbrk(str, "\\: ") = '*';
00157 strcat(str, mem_name);
00158
00159
00160 p = str;
00161 while (*p)
00162 *p++ = (char) toupper(*p);
00163
00164 hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, str);
00165 if (hMap == 0) {
00166 hFile = CreateFile(file_name, GENERIC_READ | GENERIC_WRITE,
00167 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
00168 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
00169 if (!hFile) {
00170 cm_msg(MERROR, "ss_shm_open", "CreateFile() failed");
00171 return SS_FILE_ERROR;
00172 }
00173
00174 file_size = GetFileSize(hFile, NULL);
00175 if (file_size != 0xFFFFFFFF && file_size > 0)
00176 size = file_size;
00177
00178 hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, size, str);
00179
00180 if (!hMap) {
00181 status = GetLastError();
00182 cm_msg(MERROR, "ss_shm_open", "CreateFileMapping() failed, error %d", status);
00183 return SS_FILE_ERROR;
00184 }
00185
00186 CloseHandle(hFile);
00187 status = SS_CREATED;
00188 }
00189
00190 *adr = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
00191 *handle = (HNDLE) hMap;
00192
00193 if (adr == NULL) {
00194 cm_msg(MERROR, "ss_shm_open", "MapViewOfFile() failed");
00195 return SS_NO_MEMORY;
00196 }
00197
00198 return status;
00199 }
00200
00201 #endif
00202 #ifdef OS_VMS
00203
00204 status = SS_SUCCESS;
00205
00206 {
00207 int addr[2];
00208 $DESCRIPTOR(memname_dsc, "dummy");
00209 $DESCRIPTOR(filename_dsc, "dummy");
00210 memname_dsc.dsc$w_length = strlen(mem_name);
00211 memname_dsc.dsc$a_pointer = mem_name;
00212 filename_dsc.dsc$w_length = strlen(file_name);
00213 filename_dsc.dsc$a_pointer = file_name;
00214
00215 addr[0] = size;
00216 addr[1] = 0;
00217
00218 status = ppl$create_shared_memory(&memname_dsc, addr, &PPL$M_NOUNI, &filename_dsc);
00219
00220 if (status == PPL$_CREATED)
00221 status = SS_CREATED;
00222 else if (status != PPL$_NORMAL)
00223 status = SS_FILE_ERROR;
00224
00225 *adr = (void *) addr[1];
00226 *handle = 0;
00227
00228 if (adr == NULL)
00229 return SS_NO_MEMORY;
00230
00231 return status;
00232 }
00233
00234 #endif
00235 #ifdef OS_UNIX
00236
00237 status = SS_SUCCESS;
00238
00239 {
00240 int key, shmid, fh, file_size;
00241 struct shmid_ds buf;
00242
00243
00244 key = ftok(file_name, 'M');
00245
00246
00247 if (key == -1) {
00248 fh = open(file_name, O_CREAT | O_TRUNC | O_BINARY, 0644);
00249 close(fh);
00250 key = ftok(file_name, 'M');
00251
00252 if (key == -1) {
00253 cm_msg(MERROR, "ss_shm_open", "ftok() failed");
00254 return SS_FILE_ERROR;
00255 }
00256
00257 status = SS_CREATED;
00258
00259
00260
00261 shmid = shmget(key, 0, 0);
00262 shmctl(shmid, IPC_RMID, &buf);
00263 } else {
00264
00265 file_size = (INT) ss_file_size(file_name);
00266 if (file_size > 0) {
00267 if (file_size < size) {
00268 cm_msg(MERROR, "ss_shm_open",
00269 "Shared memory segment \'%s\' size %d is smaller than requested size %d. Please remove it and try again",
00270 file_name, file_size, size);
00271 return SS_NO_MEMORY;
00272 }
00273
00274 size = file_size;
00275 }
00276 }
00277
00278
00279 shmid = shmget(key, size, 0);
00280 if (shmid == -1) {
00281
00282 shmid = shmget(key, size, IPC_CREAT | IPC_EXCL);
00283 if (shmid == -1 && errno == EEXIST) {
00284 cm_msg(MERROR, "ss_shm_open",
00285 "Shared memory segment with key 0x%x already exists, please remove it manually: ipcrm -M 0x%x",
00286 key, key);
00287 return SS_NO_MEMORY;
00288 }
00289 status = SS_CREATED;
00290 }
00291
00292 if (shmid == -1) {
00293 cm_msg(MERROR, "ss_shm_open", "shmget(key=0x%x,size=%d) failed, errno %d (%s)",
00294 key, size, errno, strerror(errno));
00295 return SS_NO_MEMORY;
00296 }
00297
00298 buf.shm_perm.uid = getuid();
00299 buf.shm_perm.gid = getgid();
00300 buf.shm_perm.mode = 0666;
00301 shmctl(shmid, IPC_SET, &buf);
00302
00303 *adr = shmat(shmid, 0, 0);
00304 *handle = (HNDLE) shmid;
00305
00306 if ((*adr) == (void *) (-1)) {
00307 cm_msg(MERROR, "ss_shm_open", "shmat(shmid=%d) failed, errno %d (%s)", shmid,
00308 errno, strerror(errno));
00309 return SS_NO_MEMORY;
00310 }
00311
00312
00313 if (status == SS_CREATED) {
00314 fh = open(file_name, O_RDONLY, 0644);
00315 if (fh == -1)
00316 fh = open(file_name, O_CREAT | O_RDWR, 0644);
00317 else
00318 read(fh, *adr, size);
00319 close(fh);
00320 }
00321
00322 return status;
00323 }
00324
00325 #endif
00326 }
00327
00328
00329 INT ss_shm_close(char *name, void *adr, HNDLE handle, INT destroy_flag)
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 {
00354 char mem_name[256], file_name[256], path[256];
00355
00356
00357
00358
00359
00360 sprintf(mem_name, "SM_%s", name);
00361
00362
00363 cm_get_path(path);
00364 if (path[0] == 0) {
00365 getcwd(path, 256);
00366 #if defined(OS_VMS)
00367 #elif defined(OS_UNIX)
00368 strcat(path, "/");
00369 #elif defined(OS_WINNT)
00370 strcat(path, "\\");
00371 #endif
00372 }
00373
00374 strcpy(file_name, path);
00375 #if defined (OS_UNIX)
00376 strcat(file_name, ".");
00377 #endif
00378 strcat(file_name, name);
00379 strcat(file_name, ".SHM");
00380
00381 #ifdef OS_WINNT
00382
00383 if (!UnmapViewOfFile(adr))
00384 return SS_INVALID_ADDRESS;
00385
00386 CloseHandle((HANDLE) handle);
00387
00388 return SS_SUCCESS;
00389
00390 #endif
00391 #ifdef OS_VMS
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 return SS_INVALID_ADDRESS;
00416
00417 #endif
00418 #ifdef OS_UNIX
00419
00420 {
00421 struct shmid_ds buf;
00422 FILE *fh;
00423
00424
00425 if (shmctl(handle, IPC_STAT, &buf) < 0) {
00426 cm_msg(MERROR, "ss_shm_close", "shmctl(shmid=%d,IPC_STAT) failed, errno %d (%s)",
00427 handle, errno, strerror(errno));
00428 return SS_INVALID_HANDLE;
00429 }
00430
00431
00432 if (buf.shm_nattch == 1) {
00433 if (!disable_shm_write) {
00434 fh = fopen(file_name, "w");
00435
00436 if (fh == NULL) {
00437 cm_msg(MERROR, "ss_shm_close",
00438 "Cannot write to file %s, please check protection", file_name);
00439 } else {
00440
00441 fwrite(adr, 1, buf.shm_segsz, fh);
00442 fclose(fh);
00443 }
00444 }
00445
00446 if (shmdt(adr) < 0) {
00447 cm_msg(MERROR, "ss_shm_close", "shmdt(shmid=%d) failed, errno %d (%s)",
00448 handle, errno, strerror(errno));
00449 return SS_INVALID_ADDRESS;
00450 }
00451
00452 if (shmctl(handle, IPC_RMID, &buf) < 0) {
00453 cm_msg(MERROR, "ss_shm_close",
00454 "shmctl(shmid=%d,IPC_RMID) failed, errno %d (%s)", handle, errno,
00455 strerror(errno));
00456 return SS_INVALID_ADDRESS;
00457 }
00458 } else
00459
00460 if (shmdt(adr) < 0) {
00461 cm_msg(MERROR, "ss_shm_close", "shmdt(shmid=%d) failed, errno %d (%s)", handle,
00462 errno, strerror(errno));
00463 return SS_INVALID_ADDRESS;
00464 }
00465
00466 return SS_SUCCESS;
00467 }
00468
00469 #endif
00470 }
00471
00472
00473 INT ss_shm_protect(HNDLE handle, void *adr)
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493 {
00494 #ifdef OS_WINNT
00495
00496 if (!UnmapViewOfFile(adr))
00497 return SS_INVALID_ADDRESS;
00498
00499 #endif
00500 #ifdef OS_UNIX
00501
00502 if (shmdt(adr) < 0) {
00503 cm_msg(MERROR, "ss_shm_protect", "shmdt() failed");
00504 return SS_INVALID_ADDRESS;
00505 }
00506 #endif
00507 return SS_SUCCESS;
00508 }
00509
00510
00511 INT ss_shm_unprotect(HNDLE handle, void **adr)
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531 {
00532 #ifdef OS_WINNT
00533
00534 *adr = MapViewOfFile((HANDLE) handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
00535
00536 if (*adr == NULL) {
00537 cm_msg(MERROR, "ss_shm_unprotect", "MapViewOfFile() failed");
00538 return SS_NO_MEMORY;
00539 }
00540 #endif
00541 #ifdef OS_UNIX
00542
00543 *adr = shmat(handle, 0, 0);
00544
00545 if ((*adr) == (void *) (-1)) {
00546 cm_msg(MERROR, "ss_shm_unprotect", "shmat() failed, errno = %d", errno);
00547 return SS_NO_MEMORY;
00548 }
00549 #endif
00550
00551 return SS_SUCCESS;
00552 }
00553
00554
00555 INT ss_shm_flush(char *name, void *adr, INT size)
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 {
00576 char mem_name[256], file_name[256], path[256];
00577
00578
00579
00580
00581
00582 sprintf(mem_name, "SM_%s", name);
00583
00584
00585 cm_get_path(path);
00586 if (path[0] == 0) {
00587 getcwd(path, 256);
00588 #if defined(OS_VMS)
00589 #elif defined(OS_UNIX)
00590 strcat(path, "/");
00591 #elif defined(OS_WINNT)
00592 strcat(path, "\\");
00593 #endif
00594 }
00595
00596 strcpy(file_name, path);
00597 #if defined (OS_UNIX)
00598 strcat(file_name, ".");
00599 #endif
00600 strcat(file_name, name);
00601 strcat(file_name, ".SHM");
00602
00603 #ifdef OS_WINNT
00604
00605 if (!FlushViewOfFile(adr, size))
00606 return SS_INVALID_ADDRESS;
00607
00608 return SS_SUCCESS;
00609
00610 #endif
00611 #ifdef OS_VMS
00612
00613 return SS_SUCCESS;
00614
00615 #endif
00616 #ifdef OS_UNIX
00617
00618 if (!disable_shm_write) {
00619 FILE *fh;
00620
00621 fh = fopen(file_name, "w");
00622
00623 if (fh == NULL) {
00624 cm_msg(MERROR, "ss_shm_flush",
00625 "Cannot write to file %s, please check protection", file_name);
00626 } else {
00627
00628 fwrite(adr, 1, size, fh);
00629 fclose(fh);
00630 }
00631 }
00632 return SS_SUCCESS;
00633
00634 #endif
00635 }
00636
00637
00638 INT ss_getthandle(void)
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 {
00656 #ifdef OS_WINNT
00657 HANDLE hThread;
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
00669 GetCurrentProcess(), &hThread, THREAD_ALL_ACCESS, TRUE, 0);
00670
00671 return (INT) hThread;
00672
00673 #endif
00674 #ifdef OS_VMS
00675
00676 return 0;
00677
00678 #endif
00679 #ifdef OS_UNIX
00680
00681 return ss_getpid();
00682
00683 #endif
00684 }
00685
00686 #endif
00687
00688
00689 struct {
00690 char c;
00691 double d;
00692 } test_align;
00693
00694 INT ss_get_struct_align()
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 {
00717 return (POINTER_T) (&test_align.d) - (POINTER_T) & test_align.c;
00718 }
00719
00720
00721 INT ss_getpid(void)
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738 {
00739 #ifdef OS_WINNT
00740
00741 return (int) GetCurrentProcessId();
00742
00743 #endif
00744 #ifdef OS_VMS
00745
00746 return getpid();
00747
00748 #endif
00749 #ifdef OS_UNIX
00750
00751 return getpid();
00752
00753 #endif
00754 #ifdef OS_VXWORKS
00755
00756 return 0;
00757
00758 #endif
00759 #ifdef OS_MSDOS
00760
00761 return 0;
00762
00763 #endif
00764 }
00765
00766
00767
00768 static BOOL _single_thread = FALSE;
00769
00770 void ss_force_single_thread()
00771 {
00772 _single_thread = TRUE;
00773 }
00774
00775 INT ss_gettid(void)
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792 {
00793
00794 if (_single_thread)
00795 return 1;
00796
00797 #ifdef OS_MSDOS
00798
00799 return 0;
00800
00801 #endif
00802 #ifdef OS_WINNT
00803
00804 return (int) GetCurrentThreadId();
00805
00806 #endif
00807 #ifdef OS_VMS
00808
00809 return ss_getpid();
00810
00811 #endif
00812 #ifdef OS_UNIX
00813
00814 return ss_getpid();
00815
00816 #endif
00817 #ifdef OS_VXWORKS
00818
00819 return ss_getpid();
00820
00821 #endif
00822 }
00823
00824
00825
00826 #ifdef OS_UNIX
00827 void catch_sigchld(int signo)
00828 {
00829 int status;
00830
00831 wait(&status);
00832 return;
00833 }
00834 #endif
00835
00836 INT ss_spawnv(INT mode, char *cmdname, char *argv[])
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859 {
00860 #ifdef OS_WINNT
00861
00862 if (spawnvp(mode, cmdname, argv) < 0)
00863 return SS_INVALID_NAME;
00864
00865 return SS_SUCCESS;
00866
00867 #endif
00868
00869 #ifdef OS_MSDOS
00870
00871 spawnvp((int) mode, cmdname, argv);
00872
00873 return SS_SUCCESS;
00874
00875 #endif
00876
00877 #ifdef OS_VMS
00878
00879 {
00880 char cmdstring[500], *pc;
00881 INT i, flags, status;
00882 va_list argptr;
00883
00884 $DESCRIPTOR(cmdstring_dsc, "dummy");
00885
00886 if (mode & P_DETACH) {
00887 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
00888 cmdstring_dsc.dsc$a_pointer = cmdstring;
00889
00890 status = sys$creprc(0, &cmdstring_dsc,
00891 0, 0, 0, 0, 0, NULL, 4, 0, 0, PRC$M_DETACH);
00892 } else {
00893 flags = (mode & P_NOWAIT) ? 1 : 0;
00894
00895 for (pc = argv[0] + strlen(argv[0]); *pc != ']' && pc != argv[0]; pc--);
00896 if (*pc == ']')
00897 pc++;
00898
00899 strcpy(cmdstring, pc);
00900
00901 if (strchr(cmdstring, ';'))
00902 *strchr(cmdstring, ';') = 0;
00903
00904 strcat(cmdstring, " ");
00905
00906 for (i = 1; argv[i] != NULL; i++) {
00907 strcat(cmdstring, argv[i]);
00908 strcat(cmdstring, " ");
00909 }
00910
00911 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
00912 cmdstring_dsc.dsc$a_pointer = cmdstring;
00913
00914 status = lib$spawn(&cmdstring_dsc, 0, 0, &flags, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
00915 }
00916
00917 return BM_SUCCESS;
00918 }
00919
00920 #endif
00921 #ifdef OS_UNIX
00922 pid_t child_pid;
00923
00924 #ifdef OS_ULTRIX
00925 union wait *status;
00926 #else
00927 int status;
00928 #endif
00929
00930 if ((child_pid = fork()) < 0)
00931 return (-1);
00932
00933 if (child_pid == 0) {
00934
00935 child_pid = execvp(cmdname, argv);
00936 return SS_SUCCESS;
00937 } else {
00938
00939 if (mode == P_WAIT)
00940 #ifdef OS_ULTRIX
00941 waitpid(child_pid, status, WNOHANG);
00942 #else
00943 waitpid(child_pid, &status, WNOHANG);
00944 #endif
00945
00946 else
00947
00948 signal(SIGCHLD, catch_sigchld);
00949 }
00950
00951 return SS_SUCCESS;
00952
00953 #endif
00954 }
00955
00956
00957 INT ss_shell(int sock)
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974 {
00975 #ifdef OS_WINNT
00976
00977 HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
00978 hChildStdoutRd, hChildStdoutWr,
00979 hChildStderrRd, hChildStderrWr, hSaveStdin, hSaveStdout, hSaveStderr;
00980
00981 SECURITY_ATTRIBUTES saAttr;
00982 PROCESS_INFORMATION piProcInfo;
00983 STARTUPINFO siStartInfo;
00984 char buffer[256], cmd[256];
00985 DWORD dwRead, dwWritten, dwAvail, i, i_cmd;
00986 fd_set readfds;
00987 struct timeval timeout;
00988
00989
00990 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
00991 saAttr.bInheritHandle = TRUE;
00992 saAttr.lpSecurityDescriptor = NULL;
00993
00994
00995 hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
00996
00997
00998 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
00999 return 0;
01000
01001
01002 if (!SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
01003 return 0;
01004
01005
01006
01007 hSaveStderr = GetStdHandle(STD_ERROR_HANDLE);
01008
01009
01010 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
01011 return 0;
01012
01013
01014 if (!SetStdHandle(STD_ERROR_HANDLE, hChildStderrWr))
01015 return 0;
01016
01017
01018
01019 hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
01020
01021
01022 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
01023 return 0;
01024
01025
01026 if (!SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
01027 return 0;
01028
01029
01030 if (!DuplicateHandle(GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), &hChildStdinWrDup, 0, FALSE,
01031 DUPLICATE_SAME_ACCESS))
01032 return 0;
01033
01034 CloseHandle(hChildStdinWr);
01035
01036
01037 memset(&siStartInfo, 0, sizeof(siStartInfo));
01038 siStartInfo.cb = sizeof(STARTUPINFO);
01039 siStartInfo.lpReserved = NULL;
01040 siStartInfo.lpReserved2 = NULL;
01041 siStartInfo.cbReserved2 = 0;
01042 siStartInfo.lpDesktop = NULL;
01043 siStartInfo.dwFlags = 0;
01044
01045 if (!CreateProcess(NULL, "cmd /Q",
01046 NULL,
01047 NULL,
01048 TRUE,
01049 0,
01050 NULL,
01051 NULL,
01052 &siStartInfo,
01053 &piProcInfo))
01054 return 0;
01055
01056
01057 SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
01058 SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
01059 SetStdHandle(STD_ERROR_HANDLE, hSaveStderr);
01060
01061 i_cmd = 0;
01062
01063 do {
01064
01065 do {
01066 if (!PeekNamedPipe(hChildStderrRd, buffer, 256, &dwRead, &dwAvail, NULL))
01067 break;
01068
01069 if (dwRead > 0) {
01070 ReadFile(hChildStderrRd, buffer, 256, &dwRead, NULL);
01071 send(sock, buffer, dwRead, 0);
01072 }
01073 } while (dwAvail > 0);
01074
01075
01076 do {
01077 if (!PeekNamedPipe(hChildStdoutRd, buffer, 256, &dwRead, &dwAvail, NULL))
01078 break;
01079 if (dwRead > 0) {
01080 ReadFile(hChildStdoutRd, buffer, 256, &dwRead, NULL);
01081 send(sock, buffer, dwRead, 0);
01082 }
01083 } while (dwAvail > 0);
01084
01085
01086
01087 if (!GetExitCodeProcess(piProcInfo.hProcess, &i))
01088 break;
01089 if (i != STILL_ACTIVE)
01090 break;
01091
01092
01093 FD_ZERO(&readfds);
01094 FD_SET(sock, &readfds);
01095 timeout.tv_sec = 0;
01096 timeout.tv_usec = 100;
01097 select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
01098
01099 if (FD_ISSET(sock, &readfds)) {
01100 i = recv(sock, cmd + i_cmd, 1, 0);
01101 if (i <= 0)
01102 break;
01103
01104
01105 if (cmd[i_cmd] == 8) {
01106 if (i_cmd > 0) {
01107 send(sock, "\b \b", 3, 0);
01108 i_cmd -= 1;
01109 }
01110 } else if (cmd[i_cmd] >= ' ' || cmd[i_cmd] == 13 || cmd[i_cmd] == 10) {
01111 send(sock, cmd + i_cmd, 1, 0);
01112 i_cmd += i;
01113 }
01114 }
01115
01116
01117 if (cmd[i_cmd - 1] == 10) {
01118 WriteFile(hChildStdinWrDup, cmd, i_cmd, &dwWritten, NULL);
01119 i_cmd = 0;
01120 }
01121
01122 } while (TRUE);
01123
01124 CloseHandle(hChildStdinWrDup);
01125 CloseHandle(hChildStdinRd);
01126 CloseHandle(hChildStderrRd);
01127 CloseHandle(hChildStdoutRd);
01128
01129 return SS_SUCCESS;
01130
01131 #endif
01132
01133 #ifdef OS_UNIX
01134 #ifndef NO_PTY
01135 pid_t pid;
01136 int i, pipe;
01137 char line[32], buffer[1024], shell[32];
01138 fd_set readfds;
01139
01140 if ((pid = forkpty(&pipe, line, NULL, NULL)) < 0)
01141 return 0;
01142 else if (pid > 0) {
01143
01144
01145 do {
01146 FD_ZERO(&readfds);
01147 FD_SET(sock, &readfds);
01148 FD_SET(pipe, &readfds);
01149
01150 select(FD_SETSIZE, (void *) &readfds, NULL, NULL, NULL);
01151
01152 if (FD_ISSET(sock, &readfds)) {
01153 memset(buffer, 0, sizeof(buffer));
01154 i = recv(sock, buffer, sizeof(buffer), 0);
01155 if (i <= 0)
01156 break;
01157 if (write(pipe, buffer, i) != i)
01158 break;
01159 }
01160
01161 if (FD_ISSET(pipe, &readfds)) {
01162 memset(buffer, 0, sizeof(buffer));
01163 i = read(pipe, buffer, sizeof(buffer));
01164 if (i <= 0)
01165 break;
01166 send(sock, buffer, i, 0);
01167 }
01168
01169 } while (1);
01170 } else {
01171
01172
01173 if (getenv("SHELL"))
01174 strlcpy(shell, getenv("SHELL"), sizeof(shell));
01175 else
01176 strcpy(shell, "/bin/sh");
01177 execl(shell, shell, 0);
01178 }
01179 #else
01180 send(sock, "not implemented\n", 17, 0);
01181 #endif
01182
01183 return SS_SUCCESS;
01184
01185 #endif
01186 }
01187
01188
01189 static BOOL _daemon_flag;
01190
01191 INT ss_daemon_init(BOOL keep_stdout)
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209 {
01210 #ifdef OS_UNIX
01211
01212
01213 int i, fd, pid;
01214
01215 if ((pid = fork()) < 0)
01216 return SS_ABORT;
01217 else if (pid != 0)
01218 exit(0);
01219
01220
01221
01222 _daemon_flag = TRUE;
01223
01224
01225
01226 for (i = 0; i < 3; i++) {
01227 if (keep_stdout && ((i == 1) || (i == 2)))
01228 continue;
01229
01230 close(i);
01231 fd = open("/dev/null", O_RDWR, 0);
01232 if (fd < 0)
01233 fd = open("/dev/null", O_WRONLY, 0);
01234 if (fd < 0) {
01235 cm_msg(MERROR, "ss_system", "Can't open /dev/null");
01236 return SS_ABORT;
01237 }
01238 if (fd != i) {
01239 cm_msg(MERROR, "ss_system", "Did not get file descriptor");
01240 return SS_ABORT;
01241 }
01242 }
01243
01244 setsid();
01245 umask(0);
01246
01247 #endif
01248
01249 return SS_SUCCESS;
01250 }
01251
01252
01253 BOOL ss_existpid(INT pid)
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271 {
01272 #ifdef OS_UNIX
01273
01274 return (kill(pid, 0) == 0 ? TRUE : FALSE);
01275 #else
01276 cm_msg(MINFO, "ss_existpid", "implemented for UNIX only");
01277 return FALSE;
01278 #endif
01279 }
01280
01281
01282
01283 #endif
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303 INT ss_system(char *command)
01304 {
01305 #ifdef OS_UNIX
01306 INT childpid;
01307
01308 return ss_exec(command, &childpid);
01309
01310 #else
01311
01312 system(command);
01313 return SS_SUCCESS;
01314
01315 #endif
01316 }
01317
01318
01319 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01320
01321
01322 INT ss_exec(char *command, INT * pid)
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341 {
01342 #ifdef OS_UNIX
01343
01344
01345 int i, fd;
01346
01347 if ((*pid = fork()) < 0)
01348 return SS_ABORT;
01349 else if (*pid != 0) {
01350
01351 signal(SIGCHLD, catch_sigchld);
01352 return SS_SUCCESS;
01353 }
01354
01355
01356
01357
01358 for (i = 0; i < 256; i++)
01359 close(i);
01360
01361
01362
01363 for (i = 0; i < 3; i++) {
01364 fd = open("/dev/null", O_RDWR, 0);
01365 if (fd < 0)
01366 fd = open("/dev/null", O_WRONLY, 0);
01367 if (fd < 0) {
01368 cm_msg(MERROR, "ss_exec", "Can't open /dev/null");
01369 return SS_ABORT;
01370 }
01371 if (fd != i) {
01372 cm_msg(MERROR, "ss_exec", "Did not get file descriptor");
01373 return SS_ABORT;
01374 }
01375 }
01376
01377 setsid();
01378
01379 umask(0);
01380
01381
01382 execl("/bin/sh", "sh", "-c", command, NULL);
01383
01384 #else
01385
01386 system(command);
01387
01388 #endif
01389
01390 return SS_SUCCESS;
01391 }
01392
01393
01394 #endif
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429 midas_thread_t ss_thread_create(INT(*thread_func) (void *), void *param)
01430 {
01431 #if defined(OS_WINNT)
01432
01433 HANDLE status;
01434 DWORD thread_id;
01435
01436 if (thread_func == NULL) {
01437 return 0;
01438 }
01439
01440 status = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) thread_func,
01441 (LPVOID) param, 0, &thread_id);
01442
01443 return status == NULL ? 0 : (midas_thread_t) thread_id;
01444
01445 #elif defined(OS_MSDOS)
01446
01447 return 0;
01448
01449 #elif defined(OS_VMS)
01450
01451 return 0;
01452
01453 #elif defined(OS_VXWORKS)
01454
01455
01456
01457
01458
01459
01460
01461
01462 INT status;
01463 VX_TASK_SPAWN *ts;
01464
01465 ts = (VX_TASK_SPAWN *) param;
01466 status =
01467 taskSpawn(ts->name, ts->priority, ts->options, ts->stackSize,
01468 (FUNCPTR) thread_func, ts->arg1, ts->arg2, ts->arg3,
01469 ts->arg4, ts->arg5, ts->arg6, ts->arg7, ts->arg8, ts->arg9, ts->arg10);
01470
01471 return status == ERROR ? 0 : status;
01472
01473 #elif defined(OS_UNIX)
01474
01475 INT status;
01476 pthread_t thread_id;
01477
01478 status = pthread_create(&thread_id, NULL, (void *) thread_func, param);
01479
01480 return status != 0 ? 0 : thread_id;
01481
01482 #endif
01483 }
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503 INT ss_thread_kill(midas_thread_t thread_id)
01504 {
01505 #if defined(OS_WINNT)
01506
01507 DWORD status;
01508
01509 status = TerminateThread(thread_id, 0);
01510
01511 return status != 0 ? SS_SUCCESS : SS_NO_THREAD;
01512
01513 #elif defined(OS_MSDOS)
01514
01515 return 0;
01516
01517 #elif defined(OS_VMS)
01518
01519 return 0;
01520
01521 #elif defined(OS_VXWORKS)
01522
01523 INT status;
01524 status = taskDelete(thread_id);
01525 return status == OK ? 0 : ERROR;
01526
01527 #elif defined(OS_UNIX)
01528
01529 INT status;
01530 status = pthread_kill(thread_id, SIGKILL);
01531 return status == 0 ? SS_SUCCESS : SS_NO_THREAD;
01532
01533 #endif
01534 }
01535
01536
01537 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01538
01539
01540 static INT skip_mutex_handle = -1;
01541
01542 INT ss_mutex_create(char *name, HNDLE * mutex_handle)
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569 {
01570 char mutex_name[256], path[256], file_name[256];
01571
01572
01573 sprintf(mutex_name, "MX_%s", name);
01574
01575 #ifdef OS_VXWORKS
01576
01577
01578
01579 if ((*((SEM_ID *) mutex_handle) = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL)
01580 return SS_NO_MUTEX;
01581 return SS_CREATED;
01582
01583 #endif
01584
01585
01586 cm_get_path(path);
01587 if (path[0] == 0) {
01588 getcwd(path, 256);
01589 #if defined(OS_VMS)
01590 #elif defined(OS_UNIX)
01591 strcat(path, "/");
01592 #elif defined(OS_WINNT)
01593 strcat(path, "\\");
01594 #endif
01595 }
01596
01597 strcpy(file_name, path);
01598 #if defined (OS_UNIX)
01599 strcat(file_name, ".");
01600 #endif
01601 strcat(file_name, name);
01602 strcat(file_name, ".SHM");
01603
01604 #ifdef OS_WINNT
01605
01606 *mutex_handle = (HNDLE) CreateMutex(NULL, FALSE, mutex_name);
01607
01608 if (*mutex_handle == 0)
01609 return SS_NO_MUTEX;
01610
01611 return SS_CREATED;
01612
01613 #endif
01614 #ifdef OS_VMS
01615
01616
01617
01618 {
01619 INT status;
01620 $DESCRIPTOR(mutexname_dsc, "dummy");
01621 mutexname_dsc.dsc$w_length = strlen(mutex_name);
01622 mutexname_dsc.dsc$a_pointer = mutex_name;
01623
01624 *mutex_handle = (HNDLE) malloc(8);
01625
01626 status = sys$enqw(0, LCK$K_NLMODE, *mutex_handle, 0, &mutexname_dsc,
01627 0, 0, 0, 0, 0, 0);
01628
01629 if (status != SS$_NORMAL) {
01630 free((void *) *mutex_handle);
01631 *mutex_handle = 0;
01632 }
01633
01634 if (*mutex_handle == 0)
01635 return SS_NO_MUTEX;
01636
01637 return SS_CREATED;
01638 }
01639
01640 #endif
01641 #ifdef OS_UNIX
01642
01643 {
01644 INT key, status, fh;
01645 struct semid_ds buf;
01646
01647 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED) && !defined(OS_CYGWIN)) || defined(OS_FREEBSD)
01648 union semun arg;
01649 #else
01650 union semun {
01651 INT val;
01652 struct semid_ds *buf;
01653 ushort *array;
01654 } arg;
01655 #endif
01656
01657 status = SS_SUCCESS;
01658
01659
01660 key = ftok(file_name, 'M');
01661 if (key < 0) {
01662 fh = open(file_name, O_CREAT, 0644);
01663 close(fh);
01664 key = ftok(file_name, 'M');
01665 status = SS_CREATED;
01666 }
01667
01668
01669 *mutex_handle = (HNDLE) semget(key, 1, 0);
01670 if (*mutex_handle < 0) {
01671 *mutex_handle = (HNDLE) semget(key, 1, IPC_CREAT);
01672 status = SS_CREATED;
01673 }
01674
01675 if (*mutex_handle < 0) {
01676 cm_msg(MERROR, "ss_mutex_mutex", "semget() failed, errno = %d", errno);
01677 return SS_NO_MUTEX;
01678 }
01679
01680 buf.sem_perm.uid = getuid();
01681 buf.sem_perm.gid = getgid();
01682 buf.sem_perm.mode = 0666;
01683 arg.buf = &buf;
01684
01685 semctl(*mutex_handle, 0, IPC_SET, arg);
01686
01687
01688 if (status == SS_CREATED) {
01689 arg.val = 1;
01690 if (semctl(*mutex_handle, 0, SETVAL, arg) < 0)
01691 return SS_NO_MUTEX;
01692 }
01693
01694 return SS_SUCCESS;
01695 }
01696 #endif
01697
01698 #ifdef OS_MSDOS
01699 return SS_NO_MUTEX;
01700 #endif
01701 }
01702
01703
01704 INT ss_mutex_wait_for(HNDLE mutex_handle, INT timeout)
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724 {
01725 INT status;
01726
01727 #ifdef OS_WINNT
01728
01729 status = WaitForSingleObject((HANDLE) mutex_handle, timeout == 0 ? INFINITE : timeout);
01730 if (status == WAIT_FAILED)
01731 return SS_NO_MUTEX;
01732 if (status == WAIT_TIMEOUT)
01733 return SS_TIMEOUT;
01734
01735 return SS_SUCCESS;
01736 #endif
01737 #ifdef OS_VMS
01738 status = sys$enqw(0, LCK$K_EXMODE, mutex_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
01739 if (status != SS$_NORMAL)
01740 return SS_NO_MUTEX;
01741 return SS_SUCCESS;
01742
01743 #endif
01744 #ifdef OS_VXWORKS
01745
01746 status = semTake((SEM_ID) mutex_handle, timeout == 0 ? WAIT_FOREVER : timeout >> 4);
01747 if (status == ERROR)
01748 return SS_NO_MUTEX;
01749 return SS_SUCCESS;
01750
01751 #endif
01752 #ifdef OS_UNIX
01753 {
01754 DWORD start_time;
01755 struct sembuf sb;
01756
01757 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED) && !defined(OS_CYGWIN)) || defined(OS_FREEBSD)
01758 union semun arg;
01759 #else
01760 union semun {
01761 INT val;
01762 struct semid_ds *buf;
01763 ushort *array;
01764 } arg;
01765 #endif
01766
01767 sb.sem_num = 0;
01768 sb.sem_op = -1;
01769 sb.sem_flg = SEM_UNDO;
01770
01771 memset(&arg, 0, sizeof(arg));
01772
01773
01774
01775 if (ss_in_async_routine_flag)
01776 if (semctl(mutex_handle, 0, GETPID, arg) == getpid())
01777 if (semctl(mutex_handle, 0, GETVAL, arg) == 0) {
01778 skip_mutex_handle = mutex_handle;
01779 return SS_SUCCESS;
01780 }
01781
01782 skip_mutex_handle = -1;
01783
01784 start_time = ss_millitime();
01785
01786 do {
01787 status = semop(mutex_handle, &sb, 1);
01788
01789
01790 if (status == 0)
01791 break;
01792
01793
01794 if (errno == EINTR) {
01795
01796 if (timeout > 0 && ss_millitime() - start_time > timeout)
01797 return SS_TIMEOUT;
01798
01799 continue;
01800 }
01801
01802 return SS_NO_MUTEX;
01803 } while (1);
01804
01805 return SS_SUCCESS;
01806 }
01807 #endif
01808
01809 #ifdef OS_MSDOS
01810 return SS_NO_MUTEX;
01811 #endif
01812 }
01813
01814
01815 INT ss_mutex_release(HNDLE mutex_handle)
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833 {
01834 INT status;
01835
01836 #ifdef OS_WINNT
01837
01838 status = ReleaseMutex((HANDLE) mutex_handle);
01839
01840 if (status == FALSE)
01841 return SS_NO_MUTEX;
01842
01843 return SS_SUCCESS;
01844
01845 #endif
01846 #ifdef OS_VMS
01847
01848 status = sys$enqw(0, LCK$K_NLMODE, mutex_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
01849
01850 if (status != SS$_NORMAL)
01851 return SS_NO_MUTEX;
01852
01853 return SS_SUCCESS;
01854
01855 #endif
01856
01857 #ifdef OS_VXWORKS
01858
01859 if (semGive((SEM_ID) mutex_handle) == ERROR)
01860 return SS_NO_MUTEX;
01861 return SS_SUCCESS;
01862 #endif
01863
01864 #ifdef OS_UNIX
01865 {
01866 struct sembuf sb;
01867
01868 sb.sem_num = 0;
01869 sb.sem_op = 1;
01870 sb.sem_flg = SEM_UNDO;
01871
01872 if (mutex_handle == skip_mutex_handle) {
01873 skip_mutex_handle = -1;
01874 return SS_SUCCESS;
01875 }
01876
01877 do {
01878 status = semop(mutex_handle, &sb, 1);
01879
01880
01881 if (status == 0)
01882 break;
01883
01884
01885 if (errno == EINTR)
01886 continue;
01887
01888 return SS_NO_MUTEX;
01889 } while (1);
01890
01891 return SS_SUCCESS;
01892 }
01893 #endif
01894
01895 #ifdef OS_MSDOS
01896 return SS_NO_MUTEX;
01897 #endif
01898 }
01899
01900
01901 INT ss_mutex_delete(HNDLE mutex_handle, INT destroy_flag)
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919 {
01920 #ifdef OS_WINNT
01921
01922 if (CloseHandle((HANDLE) mutex_handle) == FALSE)
01923 return SS_NO_MUTEX;
01924
01925 return SS_SUCCESS;
01926
01927 #endif
01928 #ifdef OS_VMS
01929
01930 free((void *) mutex_handle);
01931 return SS_SUCCESS;
01932
01933 #endif
01934
01935 #ifdef OS_VXWORKS
01936
01937 if (semDelete((SEM_ID) mutex_handle) == ERROR)
01938 return SS_NO_MUTEX;
01939 return SS_SUCCESS;
01940 #endif
01941
01942 #ifdef OS_UNIX
01943 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED) && !defined(OS_CYGWIN)) || defined(OS_FREEBSD)
01944 union semun arg;
01945 #else
01946 union semun {
01947 INT val;
01948 struct semid_ds *buf;
01949 ushort *array;
01950 } arg;
01951 #endif
01952
01953 memset(&arg, 0, sizeof(arg));
01954
01955 if (destroy_flag)
01956 if (semctl(mutex_handle, 0, IPC_RMID, arg) < 0)
01957 return SS_NO_MUTEX;
01958
01959 return SS_SUCCESS;
01960
01961 #endif
01962
01963 #ifdef OS_MSDOS
01964 return SS_NO_MUTEX;
01965 #endif
01966 }
01967
01968
01969 #endif
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989 DWORD ss_millitime()
01990 {
01991 #ifdef OS_WINNT
01992
01993 return (int) GetTickCount();
01994
01995 #endif
01996 #ifdef OS_MSDOS
01997
01998 return clock() * 55;
01999
02000 #endif
02001 #ifdef OS_VMS
02002
02003 {
02004 char time[8];
02005 DWORD lo, hi;
02006
02007 sys$gettim(time);
02008
02009 lo = *((DWORD *) time);
02010 hi = *((DWORD *) (time + 4));
02011
02012
02013
02014 return lo / 10000 + hi * 429496.7296;
02015
02016 }
02017
02018 #endif
02019 #ifdef OS_UNIX
02020 {
02021 struct timeval tv;
02022
02023 gettimeofday(&tv, NULL);
02024
02025 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
02026 }
02027
02028 #endif
02029 #ifdef OS_VXWORKS
02030 {
02031 int count;
02032 static int ticks_per_msec = 0;
02033
02034 if (ticks_per_msec == 0)
02035 ticks_per_msec = 1000 / sysClkRateGet();
02036
02037 return tickGet() * ticks_per_msec;
02038 }
02039 #endif
02040 }
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056 DWORD ss_time()
02057 {
02058 #if !defined(OS_VXWORKS)
02059 #if !defined(OS_VMS)
02060 tzset();
02061 #endif
02062 #endif
02063 return (DWORD) time(NULL);
02064 }
02065
02066
02067 #ifndef DOXYGEN_SHOULD_SKIP_THIS
02068
02069
02070 DWORD ss_settime(DWORD seconds)
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086 {
02087 #if defined(OS_WINNT)
02088 SYSTEMTIME st;
02089 struct tm *ltm;
02090
02091 tzset();
02092 ltm = localtime((time_t *) & seconds);
02093
02094 st.wYear = ltm->tm_year + 1900;
02095 st.wMonth = ltm->tm_mon + 1;
02096 st.wDay = ltm->tm_mday;
02097 st.wHour = ltm->tm_hour;
02098 st.wMinute = ltm->tm_min;
02099 st.wSecond = ltm->tm_sec;
02100 st.wMilliseconds = 0;
02101
02102 SetLocalTime(&st);
02103
02104 #elif defined(OS_DARWIN)
02105
02106 assert(!"ss_settime() is not supported");
02107
02108 return SS_NO_DRIVER;
02109
02110 #elif defined(OS_CYGWIN)
02111
02112 assert(!"ss_settime() is not supported");
02113
02114 return SS_NO_DRIVER;
02115
02116 #elif defined(OS_UNIX)
02117
02118 stime((void *) &seconds);
02119
02120 #elif defined(OS_VXWORKS)
02121
02122 struct timespec ltm;
02123
02124 ltm.tv_sec = seconds;
02125 ltm.tv_nsec = 0;
02126 clock_settime(CLOCK_REALTIME, <m);
02127
02128 #endif
02129 return SS_SUCCESS;
02130 }
02131
02132
02133 char *ss_asctime()
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150 {
02151 static char str[32];
02152 time_t seconds;
02153
02154 seconds = (time_t) ss_time();
02155
02156 #if !defined(OS_VXWORKS)
02157 #if !defined(OS_VMS)
02158 tzset();
02159 #endif
02160 #endif
02161 strcpy(str, asctime(localtime(&seconds)));
02162
02163
02164 str[24] = 0;
02165
02166 return str;
02167 }
02168
02169
02170 INT ss_timezone()
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188 {
02189 #if defined(OS_DARWIN) || defined(OS_VXWORKS)
02190 return 0;
02191 #else
02192 return (INT) timezone;
02193 #endif
02194 }
02195
02196
02197
02198
02199 #ifdef OS_UNIX
02200
02201 void ss_cont()
02202 {
02203 }
02204 #endif
02205
02206
02207 #endif
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221 INT ss_sleep(INT millisec)
02222 {
02223 fd_set readfds;
02224 struct timeval timeout;
02225 int status;
02226 static int sock = 0;
02227
02228 if (millisec == 0) {
02229 #ifdef OS_WINNT
02230 SuspendThread(GetCurrentThread());
02231 #endif
02232 #ifdef OS_VMS
02233 sys$hiber();
02234 #endif
02235 #ifdef OS_UNIX
02236 signal(SIGCONT, ss_cont);
02237 pause();
02238 #endif
02239 return SS_SUCCESS;
02240 }
02241 #ifdef OS_WINNT
02242 {
02243 WSADATA WSAData;
02244
02245
02246 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
02247 return SS_SOCKET_ERROR;
02248 }
02249 #endif
02250
02251 timeout.tv_sec = millisec / 1000;
02252 timeout.tv_usec = (millisec % 1000) * 1000;
02253
02254 if (!sock)
02255 sock = socket(AF_INET, SOCK_DGRAM, 0);
02256
02257 FD_ZERO(&readfds);
02258 FD_SET(sock, &readfds);
02259 do {
02260 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
02261
02262
02263 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
02264 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
02265
02266 } while (status == -1);
02267
02268 return SS_SUCCESS;
02269 }
02270
02271
02272 #ifndef DOXYGEN_SHOULD_SKIP_THIS
02273
02274
02275 BOOL ss_kbhit()
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293 {
02294 #ifdef OS_MSDOS
02295
02296 return kbhit();
02297
02298 #endif
02299 #ifdef OS_WINNT
02300
02301 return kbhit();
02302
02303 #endif
02304 #ifdef OS_VMS
02305
02306 return FALSE;
02307
02308 #endif
02309 #ifdef OS_UNIX
02310
02311 int n;
02312
02313 if (_daemon_flag)
02314 return 0;
02315
02316 ioctl(0, FIONREAD, &n);
02317 return (n > 0);
02318
02319 #endif
02320 #ifdef OS_VXWORKS
02321
02322 int n;
02323 ioctl(0, FIONREAD, (long) &n);
02324 return (n > 0);
02325
02326 #endif
02327 }
02328
02329
02330
02331 #ifdef LOCAL_ROUTINES
02332
02333 INT ss_wake(INT pid, INT tid, INT thandle)
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355 {
02356 #ifdef OS_WINNT
02357 HANDLE process_handle;
02358 HANDLE dup_thread_handle;
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369 process_handle = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
02370
02371 if (process_handle == 0)
02372 return SS_NO_PROCESS;
02373
02374 DuplicateHandle(process_handle, (HANDLE) thandle, GetCurrentProcess(),
02375 &dup_thread_handle, THREAD_ALL_ACCESS, TRUE, 0);
02376
02377
02378 CloseHandle(process_handle);
02379
02380 if (dup_thread_handle == 0)
02381 return SS_NO_PROCESS;
02382
02383 ResumeThread(dup_thread_handle);
02384
02385
02386 CloseHandle(dup_thread_handle);
02387
02388 return SS_SUCCESS;
02389
02390 #endif
02391 #ifdef OS_VMS
02392
02393 if (sys$wake(&pid, 0) == SS$_NONEXPR)
02394 return SS_NO_PROCESS;
02395
02396 return SS_SUCCESS;
02397
02398 #endif
02399 #ifdef OS_UNIX
02400
02401 if (kill(pid, SIGCONT) < 0)
02402 return SS_NO_PROCESS;
02403
02404 return SS_SUCCESS;
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414 #endif
02415 }
02416
02417
02418 #ifdef OS_WINNT
02419
02420 static void (*UserCallback) (int);
02421 static UINT _timer_id = 0;
02422
02423 VOID CALLBACK _timeCallback(UINT idEvent, UINT uReserved, DWORD dwUser,
02424 DWORD dwReserved1, DWORD dwReserved2)
02425 {
02426 _timer_id = 0;
02427 if (UserCallback != NULL)
02428 UserCallback(0);
02429 }
02430
02431 #endif
02432
02433 INT ss_alarm(INT millitime, void (*func) (int))
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453 {
02454 #ifdef OS_WINNT
02455
02456 UserCallback = func;
02457 if (millitime > 0)
02458 _timer_id =
02459 timeSetEvent(millitime, 100, (LPTIMECALLBACK) _timeCallback, 0, TIME_ONESHOT);
02460 else {
02461 if (_timer_id)
02462 timeKillEvent(_timer_id);
02463 _timer_id = 0;
02464 }
02465
02466 return SS_SUCCESS;
02467
02468 #endif
02469 #ifdef OS_VMS
02470
02471 signal(SIGALRM, func);
02472 alarm(millitime / 1000);
02473 return SS_SUCCESS;
02474
02475 #endif
02476 #ifdef OS_UNIX
02477
02478 signal(SIGALRM, func);
02479 alarm(millitime / 1000);
02480 return SS_SUCCESS;
02481
02482 #endif
02483 }
02484
02485
02486 void (*MidasExceptionHandler) ();
02487
02488 #ifdef OS_WINNT
02489
02490 LONG MidasExceptionFilter(LPEXCEPTION_POINTERS pexcep)
02491 {
02492 if (MidasExceptionHandler != NULL)
02493 MidasExceptionHandler();
02494
02495 return EXCEPTION_CONTINUE_SEARCH;
02496 }
02497
02498 INT MidasExceptionSignal(INT sig)
02499 {
02500 if (MidasExceptionHandler != NULL)
02501 MidasExceptionHandler();
02502
02503 raise(sig);
02504
02505 return 0;
02506 }
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518 #endif
02519
02520 #ifdef OS_VMS
02521
02522 INT MidasExceptionFilter(INT * sigargs, INT * mechargs)
02523 {
02524 if (MidasExceptionHandler != NULL)
02525 MidasExceptionHandler();
02526
02527 return (SS$_RESIGNAL);
02528 }
02529
02530 void MidasExceptionSignal(INT sig)
02531 {
02532 if (MidasExceptionHandler != NULL)
02533 MidasExceptionHandler();
02534
02535 kill(getpid(), sig);
02536 }
02537
02538 #endif
02539
02540
02541 INT ss_exception_handler(void (*func) ())
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560 {
02561 #ifdef OS_WINNT
02562
02563 MidasExceptionHandler = func;
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575 #endif
02576 #ifdef OS_VMS
02577
02578 MidasExceptionHandler = func;
02579 lib$establish(MidasExceptionFilter);
02580
02581 signal(SIGINT, MidasExceptionSignal);
02582 signal(SIGILL, MidasExceptionSignal);
02583 signal(SIGQUIT, MidasExceptionSignal);
02584 signal(SIGFPE, MidasExceptionSignal);
02585 signal(SIGSEGV, MidasExceptionSignal);
02586 signal(SIGTERM, MidasExceptionSignal);
02587
02588 #endif
02589
02590 return SS_SUCCESS;
02591 }
02592
02593 #endif
02594
02595
02596 void *ss_ctrlc_handler(void (*func) (int))
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616 {
02617 #ifdef OS_WINNT
02618
02619 if (func == NULL) {
02620 signal(SIGBREAK, SIG_DFL);
02621 return signal(SIGINT, SIG_DFL);
02622 } else {
02623 signal(SIGBREAK, func);
02624 return signal(SIGINT, func);
02625 }
02626 return NULL;
02627
02628 #endif
02629 #ifdef OS_VMS
02630
02631 return signal(SIGINT, func);
02632
02633 #endif
02634
02635 #ifdef OS_UNIX
02636
02637 if (func == NULL) {
02638 signal(SIGTERM, SIG_DFL);
02639 return (void *) signal(SIGINT, SIG_DFL);
02640 } else {
02641 signal(SIGTERM, func);
02642 return (void *) signal(SIGINT, func);
02643 }
02644
02645 #endif
02646 }
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666 typedef struct {
02667 BOOL in_use;
02668 INT thread_id;
02669 INT ipc_port;
02670 INT ipc_recv_socket;
02671 INT ipc_send_socket;
02672 INT(*ipc_dispatch) (char *, INT);
02673 INT listen_socket;
02674 INT(*listen_dispatch) (INT);
02675 RPC_SERVER_CONNECTION *server_connection;
02676 INT(*client_dispatch) (INT);
02677 RPC_SERVER_ACCEPTION *server_acception;
02678 INT(*server_dispatch) (INT, int, BOOL);
02679 struct sockaddr_in bind_addr;
02680 } SUSPEND_STRUCT;
02681
02682 SUSPEND_STRUCT *_suspend_struct = NULL;
02683 INT _suspend_entries;
02684
02685
02686 INT ss_suspend_init_ipc(INT index)
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705 {
02706 INT status, sock;
02707 int i;
02708 struct sockaddr_in bind_addr;
02709 char local_host_name[HOST_NAME_LENGTH];
02710 struct hostent *phe;
02711
02712 #ifdef OS_WINNT
02713 {
02714 WSADATA WSAData;
02715
02716
02717 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
02718 return SS_SOCKET_ERROR;
02719 }
02720 #endif
02721
02722
02723 sock = socket(AF_INET, SOCK_DGRAM, 0);
02724 if (sock == -1)
02725 return SS_SOCKET_ERROR;
02726
02727
02728 memset(&bind_addr, 0, sizeof(bind_addr));
02729 bind_addr.sin_family = AF_INET;
02730 bind_addr.sin_addr.s_addr = 0;
02731 bind_addr.sin_port = 0;
02732
02733 gethostname(local_host_name, sizeof(local_host_name));
02734
02735 #ifdef OS_VXWORKS
02736 {
02737 INT host_addr;
02738
02739 host_addr = hostGetByName(local_host_name);
02740 memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
02741 }
02742 #else
02743 phe = gethostbyname(local_host_name);
02744 if (phe == NULL) {
02745 cm_msg(MERROR, "ss_suspend_init_ipc", "cannot get host name");
02746 return SS_SOCKET_ERROR;
02747 }
02748 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
02749 #endif
02750
02751 status = bind(sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
02752 if (status < 0)
02753 return SS_SOCKET_ERROR;
02754
02755
02756 i = sizeof(bind_addr);
02757 getsockname(sock, (struct sockaddr *) &bind_addr, (int *) &i);
02758
02759 _suspend_struct[index].ipc_recv_socket = sock;
02760 _suspend_struct[index].ipc_port = ntohs(bind_addr.sin_port);
02761
02762
02763 sock = socket(AF_INET, SOCK_DGRAM, 0);
02764
02765 if (sock == -1)
02766 return SS_SOCKET_ERROR;
02767
02768
02769 memset(&bind_addr, 0, sizeof(bind_addr));
02770 bind_addr.sin_family = AF_INET;
02771 bind_addr.sin_addr.s_addr = 0;
02772
02773 #ifdef OS_VXWORKS
02774 {
02775 INT host_addr;
02776
02777 host_addr = hostGetByName(local_host_name);
02778 memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
02779 }
02780 #else
02781 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
02782 #endif
02783
02784 memcpy(&_suspend_struct[index].bind_addr, &bind_addr, sizeof(bind_addr));
02785 _suspend_struct[index].ipc_send_socket = sock;
02786
02787 return SS_SUCCESS;
02788 }
02789
02790
02791 INT ss_suspend_get_index(INT * pindex)
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811 {
02812 INT index;
02813
02814 if (_suspend_struct == NULL) {
02815
02816 _suspend_struct = (SUSPEND_STRUCT *) malloc(sizeof(SUSPEND_STRUCT));
02817 memset(_suspend_struct, 0, sizeof(SUSPEND_STRUCT));
02818 if (_suspend_struct == NULL)
02819 return SS_NO_MEMORY;
02820
02821 _suspend_entries = 1;
02822 *pindex = 0;
02823 _suspend_struct[0].thread_id = ss_gettid();
02824 _suspend_struct[0].in_use = TRUE;
02825 } else {
02826
02827 for (index = 0; index < _suspend_entries; index++)
02828 if (_suspend_struct[index].thread_id == ss_gettid()) {
02829 if (pindex != NULL)
02830 *pindex = index;
02831
02832 return SS_SUCCESS;
02833 }
02834
02835
02836 for (index = 0; index < _suspend_entries; index++)
02837 if (!_suspend_struct[index].in_use)
02838 break;
02839
02840 if (index == _suspend_entries) {
02841
02842 _suspend_struct = (SUSPEND_STRUCT *) realloc(_suspend_struct,
02843 sizeof
02844 (SUSPEND_STRUCT) *
02845 (_suspend_entries + 1));
02846 memset(&_suspend_struct[_suspend_entries], 0, sizeof(SUSPEND_STRUCT));
02847
02848 _suspend_entries++;
02849 if (_suspend_struct == NULL) {
02850 _suspend_entries--;
02851 return SS_NO_MEMORY;
02852 }
02853 }
02854 *pindex = index;
02855 _suspend_struct[index].thread_id = ss_gettid();
02856 _suspend_struct[index].in_use = TRUE;
02857 }
02858
02859 return SS_SUCCESS;
02860 }
02861
02862
02863 INT ss_suspend_exit()
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881 {
02882 INT i, status;
02883
02884 status = ss_suspend_get_index(&i);
02885
02886 if (status != SS_SUCCESS)
02887 return status;
02888
02889 if (_suspend_struct[i].ipc_recv_socket) {
02890 closesocket(_suspend_struct[i].ipc_recv_socket);
02891 closesocket(_suspend_struct[i].ipc_send_socket);
02892 }
02893
02894 memset(&_suspend_struct[i], 0, sizeof(SUSPEND_STRUCT));
02895
02896
02897 for (i = _suspend_entries - 1; i >= 0; i--)
02898 if (_suspend_struct[i].in_use)
02899 break;
02900
02901 _suspend_entries = i + 1;
02902
02903 if (_suspend_entries == 0) {
02904 free(_suspend_struct);
02905 _suspend_struct = NULL;
02906 }
02907
02908 return SS_SUCCESS;
02909 }
02910
02911
02912 INT ss_suspend_set_dispatch(INT channel, void *connection, INT(*dispatch) ())
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941 {
02942 INT i, status;
02943
02944 status = ss_suspend_get_index(&i);
02945
02946 if (status != SS_SUCCESS)
02947 return status;
02948
02949 if (channel == CH_IPC) {
02950 _suspend_struct[i].ipc_dispatch = (INT(*)(char *, INT)) dispatch;
02951
02952 if (!_suspend_struct[i].ipc_recv_socket)
02953 ss_suspend_init_ipc(i);
02954 }
02955
02956 if (channel == CH_LISTEN) {
02957 _suspend_struct[i].listen_socket = *((INT *) connection);
02958 _suspend_struct[i].listen_dispatch = (INT(*)(INT)) dispatch;
02959 }
02960
02961 if (channel == CH_CLIENT) {
02962 _suspend_struct[i].server_connection = (RPC_SERVER_CONNECTION *) connection;
02963 _suspend_struct[i].client_dispatch = (INT(*)(INT)) dispatch;
02964 }
02965
02966 if (channel == CH_SERVER) {
02967 _suspend_struct[i].server_acception = (RPC_SERVER_ACCEPTION *) connection;
02968 _suspend_struct[i].server_dispatch = (INT(*)(INT, int, BOOL)) dispatch;
02969 }
02970
02971 return SS_SUCCESS;
02972 }
02973
02974
02975 INT ss_suspend_get_port(INT * port)
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996 {
02997 INT index, status;
02998
02999 status = ss_suspend_get_index(&index);
03000
03001 if (status != SS_SUCCESS)
03002 return status;
03003
03004 if (!_suspend_struct[index].ipc_port)
03005 ss_suspend_init_ipc(index);
03006
03007 *port = _suspend_struct[index].ipc_port;
03008
03009 return SS_SUCCESS;
03010 }
03011
03012
03013 INT ss_suspend(INT millisec, INT msg)
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029
03030
03031
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044 {
03045 fd_set readfds;
03046 struct timeval timeout;
03047 INT sock, server_socket;
03048 INT index, status, i, return_status;
03049 int size;
03050 struct sockaddr from_addr;
03051 char str[100], buffer[80], buffer_tmp[80];
03052
03053
03054 status = ss_suspend_get_index(&index);
03055
03056 if (status != SS_SUCCESS)
03057 return status;
03058
03059 return_status = SS_TIMEOUT;
03060
03061 do {
03062 FD_ZERO(&readfds);
03063
03064
03065 if (_suspend_struct[index].listen_socket)
03066 FD_SET(_suspend_struct[index].listen_socket, &readfds);
03067
03068
03069 if (_suspend_struct[index].server_acception)
03070 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03071
03072 sock = _suspend_struct[index].server_acception[i].recv_sock;
03073
03074
03075 if (!sock || _suspend_struct[index].server_acception[i].tid != ss_gettid())
03076 continue;
03077
03078
03079 if (recv_tcp_check(sock) == 0)
03080 FD_SET(sock, &readfds);
03081
03082
03083 else if (msg == 0)
03084 millisec = 0;
03085
03086
03087 sock = _suspend_struct[index].server_acception[i].event_sock;
03088
03089 if (!sock)
03090 continue;
03091
03092
03093 if (recv_event_check(sock) == 0)
03094 FD_SET(sock, &readfds);
03095
03096
03097 else if (msg == 0)
03098 millisec = 0;
03099 }
03100
03101
03102 if (_suspend_struct[index].server_connection) {
03103 sock = _suspend_struct[index].server_connection->recv_sock;
03104 if (sock)
03105 FD_SET(sock, &readfds);
03106 }
03107
03108
03109 if (_suspend_struct[index].ipc_recv_socket)
03110 FD_SET(_suspend_struct[index].ipc_recv_socket, &readfds);
03111
03112 timeout.tv_sec = millisec / 1000;
03113 timeout.tv_usec = (millisec % 1000) * 1000;
03114
03115 do {
03116 if (millisec < 0)
03117 status = select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
03118 else
03119 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03120
03121
03122 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
03123 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
03124
03125 } while (status == -1);
03126
03127
03128 if (_suspend_struct[index].listen_socket &&
03129 FD_ISSET(_suspend_struct[index].listen_socket, &readfds)) {
03130 sock = _suspend_struct[index].listen_socket;
03131
03132 if (_suspend_struct[index].listen_dispatch) {
03133 status = _suspend_struct[index].listen_dispatch(sock);
03134 if (status == RPC_SHUTDOWN)
03135 return status;
03136 }
03137 }
03138
03139
03140 if (_suspend_struct[index].server_acception)
03141 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03142
03143 sock = _suspend_struct[index].server_acception[i].recv_sock;
03144
03145
03146 if (!sock || _suspend_struct[index].server_acception[i].tid != ss_gettid())
03147 continue;
03148
03149 if (recv_tcp_check(sock) || FD_ISSET(sock, &readfds)) {
03150 if (_suspend_struct[index].server_dispatch) {
03151 status = _suspend_struct[index].server_dispatch(i, sock, msg != 0);
03152 _suspend_struct[index].server_acception[i].
03153 last_activity = ss_millitime();
03154
03155 if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN)
03156 return status;
03157
03158 return_status = SS_SERVER_RECV;
03159 }
03160 }
03161
03162
03163 sock = _suspend_struct[index].server_acception[i].event_sock;
03164 if (!sock)
03165 continue;
03166
03167 if (recv_event_check(sock) || FD_ISSET(sock, &readfds)) {
03168 if (_suspend_struct[index].server_dispatch) {
03169 status = _suspend_struct[index].server_dispatch(i, sock, msg != 0);
03170 _suspend_struct[index].server_acception[i].
03171 last_activity = ss_millitime();
03172
03173 if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN)
03174 return status;
03175
03176 return_status = SS_SERVER_RECV;
03177 }
03178 }
03179 }
03180
03181
03182 if (_suspend_struct[index].server_connection) {
03183 sock = _suspend_struct[index].server_connection->recv_sock;
03184
03185 if (sock && FD_ISSET(sock, &readfds)) {
03186 if (_suspend_struct[index].client_dispatch)
03187 status = _suspend_struct[index].client_dispatch(sock);
03188 else {
03189 status = SS_SUCCESS;
03190 size = recv_tcp(sock, buffer, sizeof(buffer), 0);
03191
03192 if (size <= 0)
03193 status = SS_ABORT;
03194 }
03195
03196 if (status == SS_ABORT) {
03197 sprintf(str, "Server connection broken to %s",
03198 _suspend_struct[index].server_connection->host_name);
03199 cm_msg(MINFO, "ss_suspend", str);
03200
03201
03202 closesocket(_suspend_struct[index].server_connection->send_sock);
03203 closesocket(_suspend_struct[index].server_connection->recv_sock);
03204 closesocket(_suspend_struct[index].server_connection->event_sock);
03205
03206 memset(_suspend_struct[index].server_connection,
03207 0, sizeof(RPC_CLIENT_CONNECTION));
03208
03209
03210 return SS_ABORT;
03211 }
03212
03213 return_status = SS_CLIENT_RECV;
03214 }
03215 }
03216
03217
03218 if (_suspend_struct[index].ipc_recv_socket &&
03219 FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds)) {
03220
03221 size = sizeof(struct sockaddr);
03222 size = recvfrom(_suspend_struct[index].ipc_recv_socket,
03223 buffer, sizeof(buffer), 0, &from_addr, (int *) &size);
03224
03225
03226 server_socket = 0;
03227 if (_suspend_struct[index].server_acception &&
03228 rpc_get_server_option(RPC_OSERVER_TYPE) != ST_REMOTE)
03229 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03230 sock = _suspend_struct[index].server_acception[i].send_sock;
03231 if (sock && _suspend_struct[index].server_acception[i].tid == ss_gettid())
03232 server_socket = sock;
03233 }
03234
03235
03236 do {
03237 FD_ZERO(&readfds);
03238 FD_SET(_suspend_struct[index].ipc_recv_socket, &readfds);
03239
03240 timeout.tv_sec = 0;
03241 timeout.tv_usec = 0;
03242
03243 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03244
03245 if (status != -1
03246 && FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds)) {
03247 size = sizeof(struct sockaddr);
03248 size =
03249 recvfrom(_suspend_struct[index].ipc_recv_socket,
03250 buffer_tmp, sizeof(buffer_tmp), 0, &from_addr, &size);
03251
03252
03253 if (buffer_tmp[0] != 'B' || strcmp(buffer_tmp, buffer) != 0)
03254 if (_suspend_struct[index].ipc_dispatch)
03255 _suspend_struct[index].ipc_dispatch(buffer_tmp, server_socket);
03256 }
03257
03258 } while (FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds));
03259
03260
03261 if (msg == MSG_BM && buffer[0] == 'B')
03262 return SS_SUCCESS;
03263 if (msg == MSG_ODB && buffer[0] == 'O')
03264 return SS_SUCCESS;
03265
03266
03267 if (_suspend_struct[index].ipc_dispatch)
03268 _suspend_struct[index].ipc_dispatch(buffer, server_socket);
03269
03270 return_status = SS_SUCCESS;
03271 }
03272
03273 } while (millisec < 0);
03274
03275 return return_status;
03276 }
03277
03278
03279 INT ss_resume(INT port, char *message)
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302 {
03303 INT status, index;
03304
03305 if (ss_in_async_routine_flag) {
03306
03307 index = 0;
03308 } else {
03309 status = ss_suspend_get_index(&index);
03310
03311 if (status != SS_SUCCESS)
03312 return status;
03313 }
03314
03315 _suspend_struct[index].bind_addr.sin_port = htons((short) port);
03316
03317 status = sendto(_suspend_struct[index].ipc_send_socket, message,
03318 strlen(message) + 1, 0,
03319 (struct sockaddr *) &_suspend_struct[index].bind_addr,
03320 sizeof(struct sockaddr_in));
03321
03322 if (status != (INT) strlen(message) + 1)
03323 return SS_SOCKET_ERROR;
03324
03325 return SS_SUCCESS;
03326 }
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336 INT send_tcp(int sock, char *buffer, DWORD buffer_size, INT flags)
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356 {
03357 DWORD count;
03358 INT status;
03359
03360
03361
03362 for (count = 0; (INT) count < (INT) buffer_size - NET_TCP_SIZE;) {
03363 status = send(sock, buffer + count, NET_TCP_SIZE, flags);
03364 if (status != -1)
03365 count += status;
03366 else {
03367 cm_msg(MERROR, "send_tcp",
03368 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
03369 sock, NET_TCP_SIZE, status, errno, strerror(errno));
03370 return status;
03371 }
03372 }
03373
03374 while (count < buffer_size) {
03375 status = send(sock, buffer + count, buffer_size - count, flags);
03376 if (status != -1)
03377 count += status;
03378 else {
03379 cm_msg(MERROR, "send_tcp",
03380 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
03381 sock, (int) (buffer_size - count), status, errno, strerror(errno));
03382 return status;
03383 }
03384 }
03385
03386 return count;
03387 }
03388
03389
03390 INT recv_string(int sock, char *buffer, DWORD buffer_size, INT millisec)
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412
03413
03414
03415 {
03416 INT i, status;
03417 DWORD n;
03418 fd_set readfds;
03419 struct timeval timeout;
03420
03421 n = 0;
03422 memset(buffer, 0, buffer_size);
03423
03424 do {
03425 if (millisec > 0) {
03426 FD_ZERO(&readfds);
03427 FD_SET(sock, &readfds);
03428
03429 timeout.tv_sec = millisec / 1000;
03430 timeout.tv_usec = (millisec % 1000) * 1000;
03431
03432 do {
03433 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03434
03435
03436 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
03437 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
03438
03439 } while (status == -1);
03440
03441 if (!FD_ISSET(sock, &readfds))
03442 break;
03443 }
03444
03445 i = recv(sock, buffer + n, 1, 0);
03446
03447 if (i <= 0)
03448 break;
03449
03450 n++;
03451
03452 if (n >= buffer_size)
03453 break;
03454
03455 } while (buffer[n - 1] && buffer[n - 1] != 10);
03456
03457 return n - 1;
03458 }
03459
03460
03461 INT recv_tcp(int sock, char *net_buffer, DWORD buffer_size, INT flags)
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491 {
03492 INT param_size, n_received, n;
03493 NET_COMMAND *nc;
03494
03495 if (buffer_size < sizeof(NET_COMMAND_HEADER)) {
03496 cm_msg(MERROR, "recv_tcp", "parameters too large for network buffer");
03497 return -1;
03498 }
03499
03500
03501 n_received = 0;
03502 do {
03503 #ifdef OS_UNIX
03504 do {
03505 n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
03506
03507
03508 } while (n == -1 && errno == EINTR);
03509 #else
03510 n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
03511 #endif
03512
03513 if (n <= 0) {
03514 cm_msg(MERROR, "recv_tcp",
03515 "header: recv returned %d, n_received = %d, errno: %d (%s)",
03516 n, n_received, errno, strerror(errno));
03517 return n;
03518 }
03519
03520 n_received += n;
03521
03522 } while (n_received < sizeof(NET_COMMAND_HEADER));
03523
03524
03525
03526 nc = (NET_COMMAND *) net_buffer;
03527 param_size = nc->header.param_size;
03528 n_received = 0;
03529
03530 if (param_size == 0)
03531 return sizeof(NET_COMMAND_HEADER);
03532
03533 do {
03534 #ifdef OS_UNIX
03535 do {
03536 n = recv(sock,
03537 net_buffer + sizeof(NET_COMMAND_HEADER) + n_received,
03538 param_size - n_received, flags);
03539
03540
03541 } while (n == -1 && errno == EINTR);
03542 #else
03543 n = recv(sock, net_buffer + sizeof(NET_COMMAND_HEADER) + n_received,
03544 param_size - n_received, flags);
03545 #endif
03546
03547 if (n <= 0) {
03548 cm_msg(MERROR, "recv_tcp",
03549 "param: recv returned %d, n_received = %d, errno: %d (%s)",
03550 n, n_received, errno, strerror(errno));
03551 return n;
03552 }
03553
03554 n_received += n;
03555 } while (n_received < param_size);
03556
03557 return sizeof(NET_COMMAND_HEADER) + param_size;
03558 }
03559
03560
03561 INT send_udp(int sock, char *buffer, DWORD buffer_size, INT flags)
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573
03574
03575
03576
03577
03578
03579
03580
03581
03582
03583
03584 {
03585 INT status;
03586 UDP_HEADER *udp_header;
03587 static char udp_buffer[NET_UDP_SIZE];
03588 static INT serial_number = 0, n_received = 0;
03589 DWORD i, data_size;
03590
03591 udp_header = (UDP_HEADER *) udp_buffer;
03592 data_size = NET_UDP_SIZE - sizeof(UDP_HEADER);
03593
03594
03595
03596
03597
03598 if (buffer_size >= NET_UDP_SIZE / 2 && buffer_size <= data_size) {
03599
03600
03601
03602 if (n_received) {
03603 udp_header->serial_number = UDP_FIRST | n_received;
03604 udp_header->sequence_number = ++serial_number;
03605
03606 send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03607 n_received = 0;
03608 }
03609
03610 udp_header->serial_number = UDP_FIRST | buffer_size;
03611 udp_header->sequence_number = ++serial_number;
03612
03613 memcpy(udp_header + 1, buffer, buffer_size);
03614 status = send(sock, udp_buffer, buffer_size + sizeof(UDP_HEADER), flags);
03615 if (status == (INT) buffer_size + (int) sizeof(UDP_HEADER))
03616 status -= sizeof(UDP_HEADER);
03617
03618 return status;
03619 }
03620
03621
03622
03623
03624
03625 if (buffer_size <= data_size) {
03626
03627 if (buffer_size + n_received < data_size) {
03628 memcpy(udp_buffer + sizeof(UDP_HEADER) + n_received, buffer, buffer_size);
03629
03630 n_received += buffer_size;
03631 return buffer_size;
03632 }
03633
03634
03635 udp_header->serial_number = UDP_FIRST | n_received;
03636 udp_header->sequence_number = ++serial_number;
03637
03638 status = send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03639
03640 n_received = 0;
03641
03642 memcpy(udp_header + 1, buffer, buffer_size);
03643 n_received = buffer_size;
03644
03645 return buffer_size;
03646 }
03647
03648
03649
03650
03651
03652
03653
03654 if (n_received) {
03655 udp_header->serial_number = UDP_FIRST | n_received;
03656 udp_header->sequence_number = ++serial_number;
03657
03658 send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03659 n_received = 0;
03660 }
03661
03662 for (i = 0; i < ((buffer_size - 1) / data_size); i++) {
03663 if (i == 0) {
03664 udp_header->serial_number = UDP_FIRST | buffer_size;
03665 udp_header->sequence_number = ++serial_number;
03666 } else {
03667 udp_header->serial_number = serial_number;
03668 udp_header->sequence_number = i;
03669 }
03670
03671 memcpy(udp_header + 1, buffer + i * data_size, data_size);
03672 send(sock, udp_buffer, NET_UDP_SIZE, flags);
03673 }
03674
03675
03676 udp_header->serial_number = serial_number;
03677 udp_header->sequence_number = i;
03678 memcpy(udp_header + 1, buffer + i * data_size, buffer_size - i * data_size);
03679 status =
03680 send(sock, udp_buffer, sizeof(UDP_HEADER) + buffer_size - i * data_size, flags);
03681 if ((DWORD) status == sizeof(UDP_HEADER) + buffer_size - i * data_size)
03682 return buffer_size;
03683
03684 return status;
03685 }
03686
03687
03688 INT recv_udp(int sock, char *buffer, DWORD buffer_size, INT flags)
03689
03690
03691
03692
03693
03694
03695
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706
03707
03708
03709
03710 {
03711 INT i, status;
03712 UDP_HEADER *udp_header;
03713 char udp_buffer[NET_UDP_SIZE];
03714 DWORD serial_number, sequence_number, total_buffer_size;
03715 DWORD data_size, n_received;
03716 fd_set readfds;
03717 struct timeval timeout;
03718
03719 udp_header = (UDP_HEADER *) udp_buffer;
03720 data_size = NET_UDP_SIZE - sizeof(UDP_HEADER);
03721
03722
03723 #ifdef OS_UNIX
03724 do {
03725 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03726
03727
03728 } while (i == -1 && errno == EINTR);
03729 #else
03730 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03731 #endif
03732
03733 start:
03734
03735
03736 while (!(udp_header->serial_number & UDP_FIRST)) {
03737
03738 FD_ZERO(&readfds);
03739 FD_SET(sock, &readfds);
03740
03741 timeout.tv_sec = 0;
03742 timeout.tv_usec = 100000;
03743
03744 do {
03745 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03746 } while (status == -1);
03747
03748
03749
03750
03751
03752 if (!FD_ISSET(sock, &readfds))
03753 return 0;
03754
03755 #ifdef OS_UNIX
03756 do {
03757 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03758
03759
03760 } while (i == -1 && errno == EINTR);
03761 #else
03762 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03763 #endif
03764 }
03765
03766
03767 total_buffer_size = udp_header->serial_number & ~UDP_FIRST;
03768 serial_number = udp_header->sequence_number;
03769 sequence_number = 0;
03770
03771 if (total_buffer_size <= data_size) {
03772 if (buffer_size < total_buffer_size) {
03773 memcpy(buffer, udp_header + 1, buffer_size);
03774 return buffer_size;
03775 } else {
03776 memcpy(buffer, udp_header + 1, total_buffer_size);
03777 return total_buffer_size;
03778 }
03779 }
03780
03781
03782 n_received = data_size;
03783
03784 if (buffer_size < data_size) {
03785 memcpy(buffer, udp_header + 1, buffer_size);
03786 return buffer_size;
03787 }
03788
03789 memcpy(buffer, udp_header + 1, data_size);
03790
03791
03792 do {
03793
03794 FD_ZERO(&readfds);
03795 FD_SET(sock, &readfds);
03796
03797 timeout.tv_sec = 0;
03798 timeout.tv_usec = 100000;
03799
03800 do {
03801 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03802 } while (status == -1);
03803
03804
03805
03806
03807
03808 if (!FD_ISSET(sock, &readfds))
03809 return 0;
03810
03811 #ifdef OS_UNIX
03812 do {
03813 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03814
03815
03816 } while (i == -1 && errno == EINTR);
03817 #else
03818 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03819 #endif
03820
03821 sequence_number++;
03822
03823
03824 if (udp_header->serial_number != serial_number ||
03825 udp_header->sequence_number != sequence_number)
03826
03827 goto start;
03828
03829
03830 memcpy(buffer + n_received, udp_header + 1, i - sizeof(UDP_HEADER));
03831
03832 n_received += (i - sizeof(UDP_HEADER));
03833
03834 } while (n_received < total_buffer_size);
03835
03836 return n_received;
03837 }
03838
03839
03840
03841 #ifdef OS_MSDOS
03842 #ifdef sopen
03843
03844
03845
03846
03847
03848
03849 #undef sopen
03850
03851 int sopen(const char *path, int access, int shflag, int mode)
03852 {
03853 return open(path, (access) | (shflag), mode);
03854 }
03855
03856 #endif
03857 #endif
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867 INT ss_tape_open(char *path, INT oflag, INT * channel)
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889 {
03890 #ifdef OS_UNIX
03891 struct mtop arg;
03892
03893 cm_enable_watchdog(FALSE);
03894
03895 *channel = open(path, oflag, 0644);
03896
03897 cm_enable_watchdog(TRUE);
03898
03899 if (*channel < 0)
03900 cm_msg(MERROR, "ss_tape_open", strerror(errno));
03901
03902 if (*channel < 0) {
03903 if (errno == EIO)
03904 return SS_NO_TAPE;
03905 if (errno == EBUSY)
03906 return SS_DEV_BUSY;
03907 return errno;
03908 }
03909 #ifdef MTSETBLK
03910
03911 arg.mt_op = MTSETBLK;
03912 arg.mt_count = 0;
03913
03914 ioctl(*channel, MTIOCTOP, &arg);
03915 #endif
03916
03917 #endif
03918
03919 #ifdef OS_WINNT
03920 INT status;
03921 TAPE_GET_MEDIA_PARAMETERS m;
03922
03923 *channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
03924 0, OPEN_EXISTING, 0, NULL);
03925
03926 if (*channel == (INT) INVALID_HANDLE_VALUE) {
03927 status = GetLastError();
03928 if (status == ERROR_SHARING_VIOLATION) {
03929 cm_msg(MERROR, "ss_tape_open", "tape is used by other process");
03930 return SS_DEV_BUSY;
03931 }
03932 if (status == ERROR_FILE_NOT_FOUND) {
03933 cm_msg(MERROR, "ss_tape_open", "tape device \"%s\" doesn't exist", path);
03934 return SS_NO_TAPE;
03935 }
03936
03937 cm_msg(MERROR, "ss_tape_open", "unknown error %d", status);
03938 return status;
03939 }
03940
03941 status = GetTapeStatus((HANDLE) (*channel));
03942 if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
03943 cm_msg(MERROR, "ss_tape_open", "no media in drive");
03944 return SS_NO_TAPE;
03945 }
03946
03947
03948 memset(&m, 0, sizeof(m));
03949 m.BlockSize = TAPE_BUFFER_SIZE;
03950 SetTapeParameters((HANDLE) (*channel), SET_TAPE_MEDIA_INFORMATION, &m);
03951
03952 #endif
03953
03954 return SS_SUCCESS;
03955 }
03956
03957
03958 INT ss_tape_close(INT channel)
03959
03960
03961
03962
03963
03964
03965
03966
03967
03968
03969
03970
03971
03972
03973
03974
03975
03976 {
03977 INT status;
03978
03979 #ifdef OS_UNIX
03980
03981 status = close(channel);
03982
03983 if (status < 0) {
03984 cm_msg(MERROR, "ss_tape_close", strerror(errno));
03985 return errno;
03986 }
03987 #endif
03988
03989 #ifdef OS_WINNT
03990
03991 if (!CloseHandle((HANDLE) channel)) {
03992 status = GetLastError();
03993 cm_msg(MERROR, "ss_tape_close", "unknown error %d", status);
03994 return status;
03995 }
03996 #endif
03997
03998 return SS_SUCCESS;
03999 }
04000
04001
04002 INT ss_tape_status(char *path)
04003
04004
04005
04006
04007
04008
04009
04010
04011
04012
04013
04014
04015
04016
04017
04018
04019 {
04020 #ifdef OS_UNIX
04021 char str[256];
04022
04023 sprintf(str, "mt -f %s status", path);
04024 system(str);
04025 #endif
04026
04027 #ifdef OS_WINNT
04028 INT status, channel;
04029 DWORD size;
04030 TAPE_GET_MEDIA_PARAMETERS m;
04031 TAPE_GET_DRIVE_PARAMETERS d;
04032 double x;
04033
04034 channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
04035 0, OPEN_EXISTING, 0, NULL);
04036
04037 if (channel == (INT) INVALID_HANDLE_VALUE) {
04038 status = GetLastError();
04039 if (status == ERROR_SHARING_VIOLATION) {
04040 cm_msg(MINFO, "ss_tape_status", "tape is used by other process");
04041 return SS_SUCCESS;
04042 }
04043 if (status == ERROR_FILE_NOT_FOUND) {
04044 cm_msg(MINFO, "ss_tape_status", "tape device \"%s\" doesn't exist", path);
04045 return SS_SUCCESS;
04046 }
04047
04048 cm_msg(MINFO, "ss_tape_status", "unknown error %d", status);
04049 return status;
04050 }
04051
04052
04053 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04054 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04055
04056 status = GetTapeStatus((HANDLE) channel);
04057 if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
04058 cm_msg(MINFO, "ss_tape_status", "no media in drive");
04059 CloseHandle((HANDLE) channel);
04060 return SS_SUCCESS;
04061 }
04062
04063 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04064 GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION, &size, &m);
04065
04066 printf("Hardware error correction is %s\n", d.ECC ? "on" : "off");
04067 printf("Hardware compression is %s\n", d.Compression ? "on" : "off");
04068 printf("Tape %s write protected\n", m.WriteProtected ? "is" : "is not");
04069
04070 if (d.FeaturesLow & TAPE_DRIVE_TAPE_REMAINING) {
04071 x = ((double) m.Remaining.LowPart + (double) m.Remaining.HighPart * 4.294967295E9)
04072 / 1024.0 / 1000.0;
04073 printf("Tape capacity remaining is %d MB\n", (int) x);
04074 } else
04075 printf("Tape capacity is not reported by tape\n");
04076
04077 CloseHandle((HANDLE) channel);
04078
04079 #endif
04080
04081 return SS_SUCCESS;
04082 }
04083
04084
04085 INT ss_tape_write(INT channel, void *pdata, INT count)
04086
04087
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104
04105
04106 {
04107 #ifdef OS_UNIX
04108 INT status;
04109
04110 do {
04111 status = write(channel, pdata, count);
04112
04113
04114
04115
04116 } while (status == -1 && errno == EINTR);
04117
04118 if (status != count) {
04119 cm_msg(MERROR, "ss_tape_write", strerror(errno));
04120
04121 if (errno == EIO)
04122 return SS_IO_ERROR;
04123 else
04124 return SS_TAPE_ERROR;
04125 }
04126 #endif
04127
04128 #ifdef OS_WINNT
04129 INT status;
04130 DWORD written;
04131
04132 WriteFile((HANDLE) channel, pdata, count, &written, NULL);
04133 if (written != (DWORD) count) {
04134 status = GetLastError();
04135 cm_msg(MERROR, "ss_tape_write", "error %d", status);
04136
04137 return SS_IO_ERROR;
04138 }
04139 #endif
04140
04141 return SS_SUCCESS;
04142 }
04143
04144
04145 INT ss_tape_read(INT channel, void *pdata, INT * count)
04146
04147
04148
04149
04150
04151
04152
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165 {
04166 #ifdef OS_UNIX
04167 INT n, status;
04168
04169 do {
04170 n = read(channel, pdata, *count);
04171 } while (n == -1 && errno == EINTR);
04172
04173 if (n == -1) {
04174 if (errno == ENOSPC || errno == EIO)
04175 status = SS_END_OF_TAPE;
04176 else {
04177 if (n == 0 && errno == 0)
04178 status = SS_END_OF_FILE;
04179 else {
04180 cm_msg(MERROR, "ss_tape_read",
04181 "unexpected tape error: n=%d, errno=%d\n", n, errno);
04182 status = errno;
04183 }
04184 }
04185 } else
04186 status = SS_SUCCESS;
04187 *count = n;
04188
04189 return status;
04190
04191 #elif defined(OS_WINNT)
04192
04193 INT status;
04194 DWORD read;
04195
04196 if (!ReadFile((HANDLE) channel, pdata, *count, &read, NULL)) {
04197 status = GetLastError();
04198 if (status == ERROR_NO_DATA_DETECTED)
04199 status = SS_END_OF_TAPE;
04200 else if (status == ERROR_FILEMARK_DETECTED)
04201 status = SS_END_OF_FILE;
04202 else if (status == ERROR_MORE_DATA)
04203 status = SS_SUCCESS;
04204 else
04205 cm_msg(MERROR, "ss_tape_read",
04206 "unexpected tape error: n=%d, errno=%d\n", read, status);
04207 } else
04208 status = SS_SUCCESS;
04209
04210 *count = read;
04211 return status;
04212
04213 #else
04214
04215 return SS_SUCCESS;
04216
04217 #endif
04218 }
04219
04220
04221 INT ss_tape_write_eof(INT channel)
04222
04223
04224
04225
04226
04227
04228
04229
04230
04231
04232
04233
04234
04235
04236
04237
04238
04239 {
04240 INT status;
04241
04242 #ifdef OS_UNIX
04243 struct mtop arg;
04244
04245 arg.mt_op = MTWEOF;
04246 arg.mt_count = 1;
04247
04248 cm_enable_watchdog(FALSE);
04249
04250 status = ioctl(channel, MTIOCTOP, &arg);
04251
04252 cm_enable_watchdog(TRUE);
04253
04254 if (status < 0) {
04255 cm_msg(MERROR, "ss_tape_write_eof", strerror(errno));
04256 return errno;
04257 }
04258 #endif
04259
04260 #ifdef OS_WINNT
04261
04262 TAPE_GET_DRIVE_PARAMETERS d;
04263 DWORD size;
04264
04265 size = sizeof(TAPE_GET_DRIVE_PARAMETERS);
04266 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04267
04268 if (d.FeaturesHigh & TAPE_DRIVE_WRITE_FILEMARKS)
04269 status = WriteTapemark((HANDLE) channel, TAPE_FILEMARKS, 1, FALSE);
04270 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_LONG_FMKS)
04271 status = WriteTapemark((HANDLE) channel, TAPE_LONG_FILEMARKS, 1, FALSE);
04272 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_SHORT_FMKS)
04273 status = WriteTapemark((HANDLE) channel, TAPE_SHORT_FILEMARKS, 1, FALSE);
04274 else
04275 cm_msg(MERROR, "ss_tape_write_eof", "tape doesn't support writing of filemarks");
04276
04277 if (status != NO_ERROR) {
04278 cm_msg(MERROR, "ss_tape_write_eof", "unknown error %d", status);
04279 return status;
04280 }
04281 #endif
04282
04283 return SS_SUCCESS;
04284 }
04285
04286
04287 INT ss_tape_fskip(INT channel, INT count)
04288
04289
04290
04291
04292
04293
04294
04295
04296
04297
04298
04299
04300
04301
04302
04303
04304
04305
04306 {
04307 INT status;
04308
04309 #ifdef OS_UNIX
04310 struct mtop arg;
04311
04312 if (count > 0)
04313 arg.mt_op = MTFSF;
04314 else
04315 arg.mt_op = MTBSF;
04316 arg.mt_count = abs(count);
04317
04318 cm_enable_watchdog(FALSE);
04319
04320 status = ioctl(channel, MTIOCTOP, &arg);
04321
04322 cm_enable_watchdog(TRUE);
04323
04324 if (status < 0) {
04325 cm_msg(MERROR, "ss_tape_fskip", strerror(errno));
04326 return errno;
04327 }
04328 #endif
04329
04330 #ifdef OS_WINNT
04331
04332 status = SetTapePosition((HANDLE) channel, TAPE_SPACE_FILEMARKS, 0,
04333 (DWORD) count, 0, FALSE);
04334
04335 if (status == ERROR_END_OF_MEDIA)
04336 return SS_END_OF_TAPE;
04337
04338 if (status != NO_ERROR) {
04339 cm_msg(MERROR, "ss_tape_fskip", "error %d", status);
04340 return status;
04341 }
04342 #endif
04343
04344 return SS_SUCCESS;
04345 }
04346
04347
04348 INT ss_tape_rskip(INT channel, INT count)
04349
04350
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362
04363
04364
04365
04366
04367 {
04368 INT status;
04369
04370 #ifdef OS_UNIX
04371 struct mtop arg;
04372
04373 if (count > 0)
04374 arg.mt_op = MTFSR;
04375 else
04376 arg.mt_op = MTBSR;
04377 arg.mt_count = abs(count);
04378
04379 cm_enable_watchdog(FALSE);
04380
04381 status = ioctl(channel, MTIOCTOP, &arg);
04382
04383 cm_enable_watchdog(TRUE);
04384
04385 if (status < 0) {
04386 cm_msg(MERROR, "ss_tape_rskip", strerror(errno));
04387 return errno;
04388 }
04389 #endif
04390
04391 #ifdef OS_WINNT
04392
04393 status =
04394 SetTapePosition((HANDLE) channel, TAPE_SPACE_RELATIVE_BLOCKS, 0,
04395 (DWORD) count, 0, FALSE);
04396 if (status != NO_ERROR) {
04397 cm_msg(MERROR, "ss_tape_rskip", "error %d", status);
04398 return status;
04399 }
04400 #endif
04401
04402 return CM_SUCCESS;
04403 }
04404
04405
04406 INT ss_tape_rewind(INT channel)
04407
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423
04424 {
04425 INT status;
04426
04427 #ifdef OS_UNIX
04428 struct mtop arg;
04429
04430 arg.mt_op = MTREW;
04431 arg.mt_count = 0;
04432
04433 cm_enable_watchdog(FALSE);
04434
04435 status = ioctl(channel, MTIOCTOP, &arg);
04436
04437 cm_enable_watchdog(TRUE);
04438
04439 if (status < 0) {
04440 cm_msg(MERROR, "ss_tape_rewind", strerror(errno));
04441 return errno;
04442 }
04443 #endif
04444
04445 #ifdef OS_WINNT
04446
04447 status = SetTapePosition((HANDLE) channel, TAPE_REWIND, 0, 0, 0, FALSE);
04448 if (status != NO_ERROR) {
04449 cm_msg(MERROR, "ss_tape_rewind", "error %d", status);
04450 return status;
04451 }
04452 #endif
04453
04454 return CM_SUCCESS;
04455 }
04456
04457
04458 INT ss_tape_spool(INT channel)
04459
04460
04461
04462
04463
04464
04465
04466
04467
04468
04469
04470
04471
04472
04473
04474
04475
04476 {
04477 INT status;
04478
04479 #ifdef OS_UNIX
04480 struct mtop arg;
04481
04482 #ifdef MTEOM
04483 arg.mt_op = MTEOM;
04484 #else
04485 arg.mt_op = MTSEOD;
04486 #endif
04487 arg.mt_count = 0;
04488
04489 cm_enable_watchdog(FALSE);
04490
04491 status = ioctl(channel, MTIOCTOP, &arg);
04492
04493 cm_enable_watchdog(TRUE);
04494
04495 if (status < 0) {
04496 cm_msg(MERROR, "ss_tape_rewind", strerror(errno));
04497 return errno;
04498 }
04499 #endif
04500
04501 #ifdef OS_WINNT
04502
04503 status = SetTapePosition((HANDLE) channel, TAPE_SPACE_END_OF_DATA, 0, 0, 0, FALSE);
04504 if (status != NO_ERROR) {
04505 cm_msg(MERROR, "ss_tape_spool", "error %d", status);
04506 return status;
04507 }
04508 #endif
04509
04510 return CM_SUCCESS;
04511 }
04512
04513
04514 INT ss_tape_mount(INT channel)
04515
04516
04517
04518
04519
04520
04521
04522
04523
04524
04525
04526
04527
04528
04529
04530
04531
04532 {
04533 INT status;
04534
04535 #ifdef OS_UNIX
04536 struct mtop arg;
04537
04538 #ifdef MTLOAD
04539 arg.mt_op = MTLOAD;
04540 #else
04541 arg.mt_op = MTNOP;
04542 #endif
04543 arg.mt_count = 0;
04544
04545 cm_enable_watchdog(FALSE);
04546
04547 status = ioctl(channel, MTIOCTOP, &arg);
04548
04549 cm_enable_watchdog(TRUE);
04550
04551 if (status < 0) {
04552 cm_msg(MERROR, "ss_tape_mount", strerror(errno));
04553 return errno;
04554 }
04555 #endif
04556
04557 #ifdef OS_WINNT
04558
04559 status = PrepareTape((HANDLE) channel, TAPE_LOAD, FALSE);
04560 if (status != NO_ERROR) {
04561 cm_msg(MERROR, "ss_tape_mount", "error %d", status);
04562 return status;
04563 }
04564 #endif
04565
04566 return CM_SUCCESS;
04567 }
04568
04569
04570 INT ss_tape_unmount(INT channel)
04571
04572
04573
04574
04575
04576
04577
04578
04579
04580
04581
04582
04583
04584
04585
04586
04587
04588 {
04589 INT status;
04590
04591 #ifdef OS_UNIX
04592 struct mtop arg;
04593
04594 #ifdef MTOFFL
04595 arg.mt_op = MTOFFL;
04596 #else
04597 arg.mt_op = MTUNLOAD;
04598 #endif
04599 arg.mt_count = 0;
04600
04601 cm_enable_watchdog(FALSE);
04602
04603 status = ioctl(channel, MTIOCTOP, &arg);
04604
04605 cm_enable_watchdog(TRUE);
04606
04607 if (status < 0) {
04608 cm_msg(MERROR, "ss_tape_unmount", strerror(errno));
04609 return errno;
04610 }
04611 #endif
04612
04613 #ifdef OS_WINNT
04614
04615 status = PrepareTape((HANDLE) channel, TAPE_UNLOAD, FALSE);
04616 if (status != NO_ERROR) {
04617 cm_msg(MERROR, "ss_tape_unmount", "error %d", status);
04618 return status;
04619 }
04620 #endif
04621
04622 return CM_SUCCESS;
04623 }
04624
04625
04626 INT ss_tape_get_blockn(INT channel)
04627
04628
04629
04630
04631
04632
04633
04634
04635 {
04636 #if defined(OS_DARWIN)
04637
04638 return 0;
04639
04640 #elif defined(OS_UNIX)
04641
04642 INT status;
04643 struct mtpos arg;
04644
04645 cm_enable_watchdog(FALSE);
04646 status = ioctl(channel, MTIOCPOS, &arg);
04647 cm_enable_watchdog(TRUE);
04648 if (status < 0) {
04649 if (errno == EIO)
04650 return 0;
04651 else {
04652 cm_msg(MERROR, "ss_tape_get_blockn", strerror(errno));
04653 return -errno;
04654 }
04655 }
04656 return (arg.mt_blkno);
04657
04658 #elif defined(OS_WINNT)
04659
04660 INT status;
04661 TAPE_GET_MEDIA_PARAMETERS media;
04662 unsigned long size;
04663
04664 status =
04665 GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION, &size, &media);
04666 return (media.PartitionCount);
04667
04668 #endif
04669 }
04670
04671
04672
04673
04674
04675
04676
04677
04678
04679
04680 double ss_disk_free(char *path)
04681
04682
04683
04684
04685
04686
04687
04688
04689
04690
04691
04692
04693
04694
04695
04696 {
04697 #ifdef OS_UNIX
04698 #if defined(OS_OSF1)
04699 struct statfs st;
04700 statfs(path, &st, sizeof(st));
04701 return (double) st.f_bavail * st.f_bsize;
04702 #elif defined(OS_LINUX)
04703 struct statfs st;
04704 statfs(path, &st);
04705 return (double) st.f_bavail * st.f_bsize;
04706 #elif defined(OS_SOLARIS)
04707 struct statvfs st;
04708 statvfs(path, &st);
04709 return (double) st.f_bavail * st.f_bsize;
04710 #elif defined(OS_IRIX)
04711 struct statfs st;
04712 statfs(path, &st, sizeof(struct statfs), 0);
04713 return (double) st.f_bfree * st.f_bsize;
04714 #else
04715 struct fs_data st;
04716 statfs(path, &st);
04717 return (double) st.fd_otsize * st.fd_bfree;
04718 #endif
04719
04720 #elif defined(OS_WINNT)
04721 DWORD SectorsPerCluster;
04722 DWORD BytesPerSector;
04723 DWORD NumberOfFreeClusters;
04724 DWORD TotalNumberOfClusters;
04725 char str[80];
04726
04727 strcpy(str, path);
04728 if (strchr(str, ':') != NULL) {
04729 *(strchr(str, ':') + 1) = 0;
04730 strcat(str, DIR_SEPARATOR_STR);
04731 GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector,
04732 &NumberOfFreeClusters, &TotalNumberOfClusters);
04733 } else
04734 GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
04735 &NumberOfFreeClusters, &TotalNumberOfClusters);
04736
04737 return (double) NumberOfFreeClusters *SectorsPerCluster * BytesPerSector;
04738 #else
04739
04740 return 1e9;
04741
04742 #endif
04743 }
04744
04745 #if defined(OS_ULTRIX) || defined(OS_WINNT)
04746 int fnmatch(const char *pat, const char *str, const int flag)
04747 {
04748 while (*str != '\0') {
04749 if (*pat == '*') {
04750 pat++;
04751 if ((str = strchr(str, *pat)) == NULL)
04752 return -1;
04753 }
04754 if (*pat == *str) {
04755 pat++;
04756 str++;
04757 } else
04758 return -1;
04759 }
04760 if (*pat == '\0')
04761 return 0;
04762 else
04763 return -1;
04764 }
04765 #endif
04766
04767 #ifdef OS_WINNT
04768 HANDLE pffile;
04769 LPWIN32_FIND_DATA lpfdata;
04770 #endif
04771 INT ss_file_find(char *path, char *pattern, char **plist)
04772
04773
04774
04775
04776
04777
04778
04779
04780
04781
04782
04783
04784
04785
04786
04787
04788
04789 {
04790 int i;
04791 #ifdef OS_UNIX
04792 DIR *dir_pointer;
04793 struct dirent *dp;
04794
04795 if ((dir_pointer = opendir(path)) == NULL)
04796 return 0;
04797 *plist = (char *) malloc(MAX_STRING_LENGTH);
04798 i = 0;
04799 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
04800 if (fnmatch(pattern, dp->d_name, 0) == 0) {
04801 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
04802 strncpy(*plist + (i * MAX_STRING_LENGTH), dp->d_name, strlen(dp->d_name));
04803 *(*plist + (i * MAX_STRING_LENGTH) + strlen(dp->d_name)) = '\0';
04804 i++;
04805 seekdir(dir_pointer, telldir(dir_pointer));
04806 }
04807 }
04808 closedir(dir_pointer);
04809 #endif
04810 #ifdef OS_WINNT
04811 char str[255];
04812 int first;
04813
04814 strcpy(str, path);
04815 strcat(str, "\\");
04816 strcat(str, pattern);
04817 first = 1;
04818 i = 0;
04819 lpfdata = (WIN32_FIND_DATA *) malloc(sizeof(WIN32_FIND_DATA));
04820 *plist = (char *) malloc(MAX_STRING_LENGTH);
04821 pffile = FindFirstFile(str, lpfdata);
04822 if (pffile == INVALID_HANDLE_VALUE)
04823 return 0;
04824 first = 0;
04825 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
04826 strncpy(*plist + (i * MAX_STRING_LENGTH), lpfdata->cFileName,
04827 strlen(lpfdata->cFileName));
04828 *(*plist + (i * MAX_STRING_LENGTH) + strlen(lpfdata->cFileName)) = '\0';
04829 i++;
04830 while (FindNextFile(pffile, lpfdata)) {
04831 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
04832 strncpy(*plist + (i * MAX_STRING_LENGTH), lpfdata->cFileName,
04833 strlen(lpfdata->cFileName));
04834 *(*plist + (i * MAX_STRING_LENGTH) + strlen(lpfdata->cFileName)) = '\0';
04835 i++;
04836 }
04837 free(lpfdata);
04838 #endif
04839 return i;
04840 }
04841
04842 INT ss_file_remove(char *path)
04843
04844
04845
04846
04847
04848
04849
04850
04851
04852
04853
04854
04855
04856
04857
04858 {
04859 return remove(path);
04860 }
04861
04862 double ss_file_size(char *path)
04863
04864
04865
04866
04867
04868
04869
04870
04871
04872
04873
04874
04875
04876
04877
04878 {
04879 struct stat stat_buf;
04880
04881
04882 stat(path, &stat_buf);
04883 return (double) stat_buf.st_size;
04884 }
04885
04886 double ss_disk_size(char *path)
04887
04888
04889
04890
04891
04892
04893
04894
04895
04896
04897
04898
04899
04900
04901
04902 {
04903 #ifdef OS_UNIX
04904 #if defined(OS_OSF1)
04905 struct statfs st;
04906 statfs(path, &st, sizeof(st));
04907 return (double) st.f_blocks * st.f_fsize;
04908 #elif defined(OS_LINUX)
04909 struct statfs st;
04910 statfs(path, &st);
04911 return (double) st.f_blocks * st.f_bsize;
04912 #elif defined(OS_SOLARIS)
04913 struct statvfs st;
04914 statvfs(path, &st);
04915 if (st.f_frsize > 0)
04916 return (double) st.f_blocks * st.f_frsize;
04917 else
04918 return (double) st.f_blocks * st.f_bsize;
04919 #elif defined(OS_ULTRIX)
04920 struct fs_data st;
04921 statfs(path, &st);
04922 return (double) st.fd_btot * 1024;
04923 #elif defined(OS_IRIX)
04924 struct statfs st;
04925 statfs(path, &st, sizeof(struct statfs), 0);
04926 return (double) st.f_blocks * st.f_bsize;
04927 #else
04928 #error ss_disk_size not defined for this OS
04929 #endif
04930 #endif
04931
04932 #ifdef OS_WINNT
04933 DWORD SectorsPerCluster;
04934 DWORD BytesPerSector;
04935 DWORD NumberOfFreeClusters;
04936 DWORD TotalNumberOfClusters;
04937 char str[80];
04938
04939 strcpy(str, path);
04940 if (strchr(str, ':') != NULL) {
04941 *(strchr(str, ':') + 1) = 0;
04942 strcat(str, DIR_SEPARATOR_STR);
04943 GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector,
04944 &NumberOfFreeClusters, &TotalNumberOfClusters);
04945 } else
04946 GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
04947 &NumberOfFreeClusters, &TotalNumberOfClusters);
04948
04949 return (double) TotalNumberOfClusters *SectorsPerCluster * BytesPerSector;
04950 #endif
04951
04952 return 1e9;
04953 }
04954
04955
04956
04957
04958
04959
04960
04961
04962
04963 void ss_clear_screen()
04964
04965
04966
04967
04968
04969
04970
04971
04972
04973
04974
04975
04976
04977
04978
04979
04980 {
04981 #ifdef OS_WINNT
04982
04983 HANDLE hConsole;
04984 COORD coordScreen = { 0, 0 };
04985 BOOL bSuccess;
04986 DWORD cCharsWritten;
04987 CONSOLE_SCREEN_BUFFER_INFO csbi;
04988 DWORD dwConSize;
04989
04990 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
04991
04992
04993 bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
04994 dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
04995
04996
04997 bSuccess = FillConsoleOutputCharacter(hConsole, (TCHAR) ' ',
04998 dwConSize, coordScreen, &cCharsWritten);
04999
05000
05001 bSuccess = SetConsoleCursorPosition(hConsole, coordScreen);
05002 return;
05003
05004 #endif
05005 #if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
05006 printf("\033[2J");
05007 #endif
05008 #ifdef OS_MSDOS
05009 clrscr();
05010 #endif
05011 }
05012
05013
05014 void ss_set_screen_size(int x, int y)
05015
05016
05017
05018
05019
05020
05021
05022
05023
05024
05025
05026
05027
05028
05029
05030
05031 {
05032 #ifdef OS_WINNT
05033
05034 HANDLE hConsole;
05035 COORD coordSize;
05036
05037 coordSize.X = (short) x;
05038 coordSize.Y = (short) y;
05039 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05040 SetConsoleScreenBufferSize(hConsole, coordSize);
05041
05042 #endif
05043 }
05044
05045
05046 void ss_printf(INT x, INT y, const char *format, ...)
05047
05048
05049
05050
05051
05052
05053
05054
05055
05056
05057
05058
05059
05060
05061
05062
05063
05064
05065
05066
05067 {
05068 char str[256];
05069 va_list argptr;
05070
05071 va_start(argptr, format);
05072 vsprintf(str, (char *) format, argptr);
05073 va_end(argptr);
05074
05075 #ifdef OS_WINNT
05076 {
05077 HANDLE hConsole;
05078 COORD dwWriteCoord;
05079 DWORD cCharsWritten;
05080
05081 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05082
05083 dwWriteCoord.X = (short) x;
05084 dwWriteCoord.Y = (short) y;
05085
05086 WriteConsoleOutputCharacter(hConsole, str, strlen(str),
05087 dwWriteCoord, &cCharsWritten);
05088 }
05089
05090 #endif
05091
05092 #if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
05093 printf("\033[%1d;%1d;H", y + 1, x + 1);
05094 printf(str);
05095 fflush(stdout);
05096 #endif
05097
05098 #ifdef OS_MSDOS
05099 gotoxy(x + 1, y + 1);
05100 cputs(str);
05101 #endif
05102 }
05103
05104
05105 char *ss_getpass(char *prompt)
05106
05107
05108
05109
05110
05111
05112
05113
05114
05115
05116
05117
05118
05119
05120
05121
05122 {
05123 static char password[32];
05124
05125 printf(prompt);
05126 memset(password, 0, sizeof(password));
05127
05128 #ifdef OS_UNIX
05129 return (char *) getpass("");
05130 #elif defined(OS_WINNT)
05131 {
05132 HANDLE hConsole;
05133 DWORD nCharsRead;
05134
05135 hConsole = GetStdHandle(STD_INPUT_HANDLE);
05136 SetConsoleMode(hConsole, ENABLE_LINE_INPUT);
05137 ReadConsole(hConsole, password, sizeof(password), &nCharsRead, NULL);
05138 SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT |
05139 ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
05140 printf("\n");
05141
05142 if (password[strlen(password) - 1] == '\r')
05143 password[strlen(password) - 1] = 0;
05144
05145 return password;
05146 }
05147 #elif defined(OS_MSDOS)
05148 {
05149 char c, *ptr;
05150
05151 ptr = password;
05152 while ((c = getchar()) != EOF && c != '\n')
05153 *ptr++ = c;
05154 *ptr = 0;
05155
05156 printf("\n");
05157 return password;
05158 }
05159 #else
05160 {
05161 ss_gets(password, 32);
05162 return password;
05163 }
05164 #endif
05165 }
05166
05167
05168 INT ss_getchar(BOOL reset)
05169
05170
05171
05172
05173
05174
05175
05176
05177
05178
05179
05180
05181
05182
05183
05184
05185
05186
05187
05188 {
05189 #ifdef OS_UNIX
05190
05191 static BOOL init = FALSE;
05192 static struct termios save_termios;
05193 struct termios buf;
05194 int i, fd;
05195 char c[3];
05196
05197 if (_daemon_flag)
05198 return 0;
05199
05200 fd = fileno(stdin);
05201
05202 if (reset) {
05203 if (init)
05204 tcsetattr(fd, TCSAFLUSH, &save_termios);
05205 init = FALSE;
05206 return 0;
05207 }
05208
05209 if (!init) {
05210 tcgetattr(fd, &save_termios);
05211 memcpy(&buf, &save_termios, sizeof(buf));
05212
05213 buf.c_lflag &= ~(ECHO | ICANON | IEXTEN);
05214
05215 buf.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON);
05216
05217 buf.c_cflag &= ~(CSIZE | PARENB);
05218 buf.c_cflag |= CS8;
05219
05220 buf.c_cc[VMIN] = 0;
05221 buf.c_cc[VTIME] = 0;
05222
05223 tcsetattr(fd, TCSAFLUSH, &buf);
05224 init = TRUE;
05225 }
05226
05227 memset(c, 0, 3);
05228 i = read(fd, c, 1);
05229
05230 if (i == 0)
05231 return 0;
05232
05233
05234 if (c[0] == 27) {
05235 i = read(fd, c, 2);
05236 if (i == 0)
05237 return 27;
05238
05239
05240 if (c[1] < 65)
05241 read(fd, c, 1);
05242
05243
05244 switch (c[1]) {
05245 case 49:
05246 return CH_HOME;
05247 case 50:
05248 return CH_INSERT;
05249 case 51:
05250 return CH_DELETE;
05251 case 52:
05252 return CH_END;
05253 case 53:
05254 return CH_PUP;
05255 case 54:
05256 return CH_PDOWN;
05257 case 65:
05258 return CH_UP;
05259 case 66:
05260 return CH_DOWN;
05261 case 67:
05262 return CH_RIGHT;
05263 case 68:
05264 return CH_LEFT;
05265 }
05266 }
05267
05268
05269 if (c[0] == 127)
05270 return CH_BS;
05271
05272 return c[0];
05273
05274 #elif defined(OS_WINNT)
05275
05276 static BOOL init = FALSE;
05277 static INT repeat_count = 0;
05278 static INT repeat_char;
05279 HANDLE hConsole;
05280 DWORD nCharsRead;
05281 INPUT_RECORD ir;
05282 OSVERSIONINFO vi;
05283
05284
05285 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05286 GetVersionEx(&vi);
05287
05288 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT) {
05289
05290 int c;
05291
05292 if (!kbhit())
05293 return 0;
05294
05295 c = getch();
05296 if (c == 224) {
05297 c = getch();
05298 switch (c) {
05299 case 71:
05300 return CH_HOME;
05301 case 72:
05302 return CH_UP;
05303 case 73:
05304 return CH_PUP;
05305 case 75:
05306 return CH_LEFT;
05307 case 77:
05308 return CH_RIGHT;
05309 case 79:
05310 return CH_END;
05311 case 80:
05312 return CH_DOWN;
05313 case 81:
05314 return CH_PDOWN;
05315 case 82:
05316 return CH_INSERT;
05317 case 83:
05318 return CH_DELETE;
05319 }
05320 }
05321 return c;
05322 }
05323
05324 hConsole = GetStdHandle(STD_INPUT_HANDLE);
05325
05326 if (reset) {
05327 SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT |
05328 ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
05329 init = FALSE;
05330 return 0;
05331 }
05332
05333 if (!init) {
05334 SetConsoleMode(hConsole, ENABLE_PROCESSED_INPUT);
05335 init = TRUE;
05336 }
05337
05338 if (repeat_count) {
05339 repeat_count--;
05340 return repeat_char;
05341 }
05342
05343 PeekConsoleInput(hConsole, &ir, 1, &nCharsRead);
05344
05345 if (nCharsRead == 0)
05346 return 0;
05347
05348 ReadConsoleInput(hConsole, &ir, 1, &nCharsRead);
05349
05350 if (ir.EventType != KEY_EVENT)
05351 return ss_getchar(0);
05352
05353 if (!ir.Event.KeyEvent.bKeyDown)
05354 return ss_getchar(0);
05355
05356 if (ir.Event.KeyEvent.wRepeatCount > 1) {
05357 repeat_count = ir.Event.KeyEvent.wRepeatCount - 1;
05358 repeat_char = ir.Event.KeyEvent.uChar.AsciiChar;
05359 return repeat_char;
05360 }
05361
05362 if (ir.Event.KeyEvent.uChar.AsciiChar)
05363 return ir.Event.KeyEvent.uChar.AsciiChar;
05364
05365 if (ir.Event.KeyEvent.dwControlKeyState & (ENHANCED_KEY)) {
05366 switch (ir.Event.KeyEvent.wVirtualKeyCode) {
05367 case 33:
05368 return CH_PUP;
05369 case 34:
05370 return CH_PDOWN;
05371 case 35:
05372 return CH_END;
05373 case 36:
05374 return CH_HOME;
05375 case 37:
05376 return CH_LEFT;
05377 case 38:
05378 return CH_UP;
05379 case 39:
05380 return CH_RIGHT;
05381 case 40:
05382 return CH_DOWN;
05383 case 45:
05384 return CH_INSERT;
05385 case 46:
05386 return CH_DELETE;
05387 }
05388
05389 return ir.Event.KeyEvent.wVirtualKeyCode;
05390 }
05391
05392 return ss_getchar(0);
05393
05394 #elif defined(OS_MSDOS)
05395
05396 int c;
05397
05398 if (!kbhit())
05399 return 0;
05400
05401 c = getch();
05402 if (!c) {
05403 c = getch();
05404 switch (c) {
05405 case 71:
05406 return CH_HOME;
05407 case 72:
05408 return CH_UP;
05409 case 73:
05410 return CH_PUP;
05411 case 75:
05412 return CH_LEFT;
05413 case 77:
05414 return CH_RIGHT;
05415 case 79:
05416 return CH_END;
05417 case 80:
05418 return CH_DOWN;
05419 case 81:
05420 return CH_PDOWN;
05421 case 82:
05422 return CH_INSERT;
05423 case 83:
05424 return CH_DELETE;
05425 }
05426 }
05427 return c;
05428
05429 #else
05430 return -1;
05431 #endif
05432 }
05433
05434
05435 char *ss_gets(char *string, int size)
05436
05437
05438
05439
05440
05441
05442
05443
05444
05445
05446
05447
05448
05449
05450
05451
05452
05453
05454 {
05455 char *p;
05456
05457 do {
05458 p = fgets(string, size, stdin);
05459 } while (p == NULL);
05460
05461
05462 if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
05463 p[strlen(p) - 1] = 0;
05464
05465 return p;
05466 }
05467
05468
05469
05470
05471
05472
05473
05474
05475
05476 INT ss_directio_give_port(INT start, INT end)
05477 {
05478 #ifdef OS_WINNT
05479
05480
05481
05482 OSVERSIONINFO vi;
05483 HANDLE hdio = 0;
05484 DWORD buffer[] = { 6, 0, 0, 0 };
05485 DWORD size;
05486
05487 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05488 GetVersionEx(&vi);
05489
05490
05491 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
05492 hdio =
05493 CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ,
05494 NULL, OPEN_EXISTING, 0, NULL);
05495 if (hdio == INVALID_HANDLE_VALUE) {
05496 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
05497 return -1;
05498 }
05499
05500
05501 buffer[1] = start;
05502 buffer[2] = end;
05503 if (!DeviceIoControl
05504 (hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
05505 return -1;
05506 }
05507
05508 return SS_SUCCESS;
05509 #else
05510 return SS_SUCCESS;
05511 #endif
05512 }
05513
05514
05515 INT ss_directio_lock_port(INT start, INT end)
05516 {
05517 #ifdef OS_WINNT
05518
05519
05520
05521 OSVERSIONINFO vi;
05522 HANDLE hdio;
05523 DWORD buffer[] = { 7, 0, 0, 0 };
05524 DWORD size;
05525
05526 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05527 GetVersionEx(&vi);
05528
05529
05530 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
05531 hdio =
05532 CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ,
05533 NULL, OPEN_EXISTING, 0, NULL);
05534 if (hdio == INVALID_HANDLE_VALUE) {
05535 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
05536 return -1;
05537 }
05538
05539
05540 buffer[1] = start;
05541 buffer[2] = end;
05542 if (!DeviceIoControl
05543 (hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
05544 return -1;
05545 }
05546
05547 return SS_SUCCESS;
05548 #else
05549 return SS_SUCCESS;
05550 #endif
05551 }
05552
05553
05554
05555
05556
05557
05558
05559
05560
05561 INT ss_syslog(const char *message)
05562
05563
05564
05565
05566
05567
05568
05569
05570
05571
05572
05573
05574
05575
05576
05577
05578 {
05579 #ifdef OS_UNIX
05580 static BOOL init = FALSE;
05581
05582 if (!init) {
05583 #ifdef OS_ULTRIX
05584 openlog("MIDAS", LOG_PID);
05585 #else
05586 openlog("MIDAS", LOG_PID, LOG_USER);
05587 #endif
05588 init = TRUE;
05589 }
05590
05591 syslog(LOG_DEBUG, message);
05592 return SS_SUCCESS;
05593 #elif defined(OS_WINNT)
05594
05595
05596
05597
05598
05599
05600
05601
05602
05603
05604
05605
05606
05607
05608
05609
05610
05611
05612
05613
05614
05615
05616
05617
05618
05619
05620
05621
05622
05623
05624 return SS_SUCCESS;
05625
05626 #else
05627
05628 return SS_SUCCESS;
05629
05630 #endif
05631 }
05632
05633
05634
05635
05636
05637
05638
05639
05640 #define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
05641
05642 char *ss_crypt(char *buf, char *salt)
05643
05644
05645
05646
05647
05648
05649
05650
05651
05652
05653
05654
05655
05656
05657
05658
05659
05660
05661
05662 {
05663 int i, seed;
05664 static char enc_pw[13];
05665
05666 memset(enc_pw, 0, sizeof(enc_pw));
05667 enc_pw[0] = salt[0];
05668 enc_pw[1] = salt[1];
05669
05670 for (i = 0; i < 8 && buf[i]; i++)
05671 enc_pw[i + 2] = buf[i];
05672 for (; i < 8; i++)
05673 enc_pw[i + 2] = 0;
05674
05675 seed = 123;
05676 for (i = 2; i < 13; i++) {
05677 seed = 5 * seed + 27 + enc_pw[i];
05678 enc_pw[i] = (char) bin_to_ascii(seed & 0x3F);
05679 }
05680
05681 return enc_pw;
05682 }
05683
05684
05685
05686
05687
05688
05689
05690
05691 double ss_nan()
05692 {
05693 double nan;
05694
05695 nan = 0;
05696 nan = 0 / nan;
05697 return nan;
05698 }
05699
05700 #ifdef OS_WINNT
05701 #include <float.h>
05702 #ifndef isnan
05703 #define isnan(x) _isnan(x)
05704 #endif
05705 #elif defined(OS_LINUX)
05706 #include <math.h>
05707 #endif
05708
05709 int ss_isnan(double x)
05710 {
05711 return isnan(x);
05712 }
05713
05714
05715 #endif
05716
05717
05718